From da61c4691314c2b784b58412dc2c866c45e46d37 Mon Sep 17 00:00:00 2001 From: AkshayaFoiger Date: Tue, 24 Dec 2024 18:41:18 +0530 Subject: [PATCH 01/21] undo commit --- crates/api_models/src/payments.rs | 17 +++++- crates/common_enums/src/enums.rs | 42 +++++++++++++++ crates/common_types/src/payments.rs | 23 ++++++++ crates/openapi/src/openapi.rs | 2 + crates/openapi/src/openapi_v2.rs | 2 + crates/router/src/connector/stripe.rs | 4 +- .../src/connector/stripe/transformers.rs | 1 + crates/router/src/core/payments/helpers.rs | 53 ++++++++++++------- .../router/src/core/payments/transformers.rs | 1 + .../router/src/core/refunds/transformers.rs | 1 + 10 files changed, 126 insertions(+), 20 deletions(-) diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index a17189440954..9b1825c32c94 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -4991,7 +4991,7 @@ pub struct PaymentStartRedirectionParams { pub profile_id: id_type::ProfileId, } -/// Fee information to be charged on the payment being collected +/// Fee information to be charged on the payment being collected via Stripe #[derive(Setter, Clone, Debug, PartialEq, serde::Serialize, ToSchema)] pub struct StripeSplitPaymentsResponse { /// Identifier for charge created for the payment @@ -5009,11 +5009,26 @@ pub struct StripeSplitPaymentsResponse { pub transfer_account_id: String, } +/// Fee information to be charged on the payment being collected via Adyen +#[derive(Setter, Clone, Debug, PartialEq, serde::Serialize, ToSchema)] +pub struct AdyenSplitPaymentResponse { + /// Unique Identifier for the split item + pub charge_id: String, + /// The amount of the split item. + #[schema(value_type = i64, example = 6540)] + pub split_amount: MinorUnit, + /// The currency of the split item. + #[schema(example = "USD", value_type = Currency)] + pub split_currency: Option, +} + #[derive(Clone, Debug, PartialEq, serde::Serialize, ToSchema)] #[serde(rename_all = "snake_case")] pub enum SplitPaymentsResponse { /// StripeSplitPaymentsResponse StripeSplitPayment(StripeSplitPaymentsResponse), + /// AdyenSplitPaymentsResponse + AdyenSplitPayment(AdyenSplitPaymentResponse), } /// Details of external authentication diff --git a/crates/common_enums/src/enums.rs b/crates/common_enums/src/enums.rs index 0833ab37e3f8..7d37a546c839 100644 --- a/crates/common_enums/src/enums.rs +++ b/crates/common_enums/src/enums.rs @@ -3613,3 +3613,45 @@ pub enum FeatureStatus { NotSupported, Supported, } + +#[derive( + Clone, + Debug, + Eq, + PartialEq, + serde::Deserialize, + serde::Serialize, + strum::Display, + strum::EnumString, + ToSchema, + Default, +)] +#[strum(serialize_all = "snake_case")] +#[serde(rename_all = "snake_case")] +pub enum AdyenSplitType { + /// Books split amount to the specified account. + BalanceAccount, + /// The aggregated amount of the interchange and scheme fees. + AcquiringFees, + /// The aggregated amount of all transaction fees. + PaymentFee, + /// The aggregated amount of Adyen's commission and markup fees. + AdyenFees, + /// The transaction fees due to Adyen under blended rates. + AdyenCommission, + /// The transaction fees due to Adyen under Interchange ++ pricing. + AdyenMarkup, + /// The fees paid to the issuer for each payment made with the card network. + Interchange, + /// The fees paid to the card scheme for using their network. + SchemeFee, + /// Your platform's commission on the payment (specified in amount), booked to your liable balance account. + Commission, + /// Allows you and your users to top up balance accounts using direct debit, card payments, or other payment methods. + TopUp, + /// The value-added tax charged on the payment, booked to your platforms liable balance account. + Vat, + /// In very specific use cases, allows you to book the specified amount to the specified account. + #[default] + Default, +} \ No newline at end of file diff --git a/crates/common_types/src/payments.rs b/crates/common_types/src/payments.rs index 0eef7ecaf2b4..549e4cecffa6 100644 --- a/crates/common_types/src/payments.rs +++ b/crates/common_types/src/payments.rs @@ -16,6 +16,8 @@ use utoipa::ToSchema; pub enum SplitPaymentsRequest { /// StripeSplitPayment StripeSplitPayment(StripeSplitPaymentRequest), + /// AdyenSplitPayment + AdyenSplitPayment(AdyenSplitPaymentRequest), } impl_to_sql_from_sql_json!(SplitPaymentsRequest); @@ -38,3 +40,24 @@ pub struct StripeSplitPaymentRequest { pub transfer_account_id: String, } impl_to_sql_from_sql_json!(StripeSplitPaymentRequest); + +#[derive( + Serialize, Deserialize, Debug, Clone, PartialEq, Eq, FromSqlRow, AsExpression, ToSchema, +)] +#[diesel(sql_type = Jsonb)] +#[serde(deny_unknown_fields)] +/// Fee information for Split Payments to be charged on the payment being collected for Adyen +pub struct AdyenSplitPaymentRequest { + /// The unique identifier of the account to which the split amount is booked + pub account: String, + /// The amount of the split item. + #[schema(value_type = i64, example = 6540)] + pub split_amount: MinorUnit, + /// Defines the part of the payment that one wants to book to the specified account. + #[schema(value_type = AdyenSplitType, example = "balance_account")] + pub split_type: enums::AdyenSplitType, + /// Unique Identifier for the split item + pub charge_id: String, +} +impl_to_sql_from_sql_json!(AdyenSplitPaymentRequest); + diff --git a/crates/openapi/src/openapi.rs b/crates/openapi/src/openapi.rs index 2f068b5609b8..b17e0a56c28e 100644 --- a/crates/openapi/src/openapi.rs +++ b/crates/openapi/src/openapi.rs @@ -216,11 +216,13 @@ Never share your secret api keys. Keep them guarded and secure. common_utils::payout_method_utils::VenmoAdditionalData, common_types::payments::SplitPaymentsRequest, common_types::payments::StripeSplitPaymentRequest, + common_types::payments::AdyenSplitPaymentRequest, common_utils::types::ChargeRefunds, common_types::refunds::SplitRefund, common_types::refunds::StripeSplitRefundRequest, api_models::payments::SplitPaymentsResponse, api_models::payments::StripeSplitPaymentsResponse, + api_models::payments::AdyenSplitPaymentsResponse, api_models::refunds::RefundRequest, api_models::refunds::RefundType, api_models::refunds::RefundResponse, diff --git a/crates/openapi/src/openapi_v2.rs b/crates/openapi/src/openapi_v2.rs index 12b0fd003559..d2dfea4a06a9 100644 --- a/crates/openapi/src/openapi_v2.rs +++ b/crates/openapi/src/openapi_v2.rs @@ -159,12 +159,14 @@ Never share your secret api keys. Keep them guarded and secure. common_utils::payout_method_utils::VenmoAdditionalData, common_types::payments::SplitPaymentsRequest, common_types::payments::StripeSplitPaymentRequest, + common_types::payments::AdyenSplitPaymentRequest, common_types::refunds::StripeSplitRefundRequest, common_utils::types::ChargeRefunds, common_types::payment_methods::PaymentMethodsEnabled, common_types::refunds::SplitRefund, api_models::payments::SplitPaymentsResponse, api_models::payments::StripeSplitPaymentsResponse, + api_models::payments::AdyenSplitPaymentsResponse, api_models::refunds::RefundRequest, api_models::refunds::RefundsCreateRequest, api_models::refunds::RefundErrorDetails, diff --git a/crates/router/src/connector/stripe.rs b/crates/router/src/connector/stripe.rs index 6d377171121c..2e4fa45ed083 100644 --- a/crates/router/src/connector/stripe.rs +++ b/crates/router/src/connector/stripe.rs @@ -777,6 +777,7 @@ impl &mut header, ); } + common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(_) => (), } } Ok(header) @@ -962,7 +963,8 @@ impl )]; header.append(&mut customer_account_header); } - } + }, + _ => (), } } Ok(header) diff --git a/crates/router/src/connector/stripe/transformers.rs b/crates/router/src/connector/stripe/transformers.rs index cb6c04c601f5..a83e795b53ee 100644 --- a/crates/router/src/connector/stripe/transformers.rs +++ b/crates/router/src/connector/stripe/transformers.rs @@ -1953,6 +1953,7 @@ impl TryFrom<(&types::PaymentsAuthorizeRouterData, MinorUnit)> for PaymentIntent }; (charges, None) } + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(_))| None => (None, item.connector_customer.to_owned().map(Secret::new)), }; diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index eda869c3a6ca..93618a92121e 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -6246,26 +6246,43 @@ pub fn validate_platform_fees_for_marketplace( amount: api::Amount, split_payments: Option, ) -> Result<(), errors::ApiErrorResponse> { - if let Some(common_types::payments::SplitPaymentsRequest::StripeSplitPayment( - stripe_split_payment, - )) = split_payments - { - match amount { - api::Amount::Zero => { - if stripe_split_payment.application_fees.get_amount_as_i64() != 0 { - return Err(errors::ApiErrorResponse::InvalidDataValue { - field_name: "split_payments.stripe_split_payment.application_fees", - }); - } + if let Some(split_payment) = split_payments { + let (field_name, split_amount_i64) = match split_payment { + common_types::payments::SplitPaymentsRequest::StripeSplitPayment(stripe_split_payment) => ( + "split_payments.stripe_split_payment.application_fees", + stripe_split_payment.application_fees.get_amount_as_i64(), + ), + common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_payment) => ( + "split_payments.adyen_split_payment.split_amount", + adyen_split_payment.split_amount.get_amount_as_i64(), + ), + }; + + validate_split_amount(amount, split_amount_i64, field_name)?; + } + Ok(()) +} + +fn validate_split_amount( + amount: api::Amount, + split_amount_i64: i64, + field_name: &'static str , +) -> Result<(), errors::ApiErrorResponse> { + match amount { + api::Amount::Zero => { + if split_amount_i64 != 0 { + return Err(errors::ApiErrorResponse::InvalidDataValue { + field_name, + }); } - api::Amount::Value(amount) => { - if stripe_split_payment.application_fees.get_amount_as_i64() > amount.into() { - return Err(errors::ApiErrorResponse::InvalidDataValue { - field_name: "split_payments.stripe_split_payment.application_fees", - }); - } + } + api::Amount::Value(amount) => { + if split_amount_i64 > amount.into() { + return ErPr(errors::ApiErrorResponse::InvalidDataValue { + field_name, + }); } } } Ok(()) -} +} \ No newline at end of file diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index d4c3877e5d97..94c529231a1b 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -2134,6 +2134,7 @@ where }, ), ), + common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(_) => None, }, }; diff --git a/crates/router/src/core/refunds/transformers.rs b/crates/router/src/core/refunds/transformers.rs index 256e4c345224..9833920690f7 100644 --- a/crates/router/src/core/refunds/transformers.rs +++ b/crates/router/src/core/refunds/transformers.rs @@ -47,6 +47,7 @@ impl TryFrom for router_request_types::SplitRefundsRequest { }, )) } + common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(_) => todo!(), // todooooo } } } From e0100792ad7dad385a7995b5d5826c6fa054ae97 Mon Sep 17 00:00:00 2001 From: "hyperswitch-bot[bot]" <148525504+hyperswitch-bot[bot]@users.noreply.github.com> Date: Fri, 27 Dec 2024 10:20:18 +0000 Subject: [PATCH 02/21] chore: run formatter --- crates/api_models/src/payments.rs | 2 +- crates/common_enums/src/enums.rs | 2 +- crates/common_types/src/payments.rs | 1 - crates/router/src/connector/stripe.rs | 2 +- .../src/connector/stripe/transformers.rs | 5 +++-- crates/router/src/core/payments/helpers.rs | 22 +++++++++---------- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index 9b1825c32c94..f78211e9d013 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -5017,7 +5017,7 @@ pub struct AdyenSplitPaymentResponse { /// The amount of the split item. #[schema(value_type = i64, example = 6540)] pub split_amount: MinorUnit, - /// The currency of the split item. + /// The currency of the split item. #[schema(example = "USD", value_type = Currency)] pub split_currency: Option, } diff --git a/crates/common_enums/src/enums.rs b/crates/common_enums/src/enums.rs index 7d37a546c839..a45eb3278be6 100644 --- a/crates/common_enums/src/enums.rs +++ b/crates/common_enums/src/enums.rs @@ -3654,4 +3654,4 @@ pub enum AdyenSplitType { /// In very specific use cases, allows you to book the specified amount to the specified account. #[default] Default, -} \ No newline at end of file +} diff --git a/crates/common_types/src/payments.rs b/crates/common_types/src/payments.rs index 549e4cecffa6..5ad9f23de520 100644 --- a/crates/common_types/src/payments.rs +++ b/crates/common_types/src/payments.rs @@ -60,4 +60,3 @@ pub struct AdyenSplitPaymentRequest { pub charge_id: String, } impl_to_sql_from_sql_json!(AdyenSplitPaymentRequest); - diff --git a/crates/router/src/connector/stripe.rs b/crates/router/src/connector/stripe.rs index 2e4fa45ed083..909a5ff7ab38 100644 --- a/crates/router/src/connector/stripe.rs +++ b/crates/router/src/connector/stripe.rs @@ -963,7 +963,7 @@ impl )]; header.append(&mut customer_account_header); } - }, + } _ => (), } } diff --git a/crates/router/src/connector/stripe/transformers.rs b/crates/router/src/connector/stripe/transformers.rs index a83e795b53ee..af87ad6e1c8a 100644 --- a/crates/router/src/connector/stripe/transformers.rs +++ b/crates/router/src/connector/stripe/transformers.rs @@ -1953,8 +1953,9 @@ impl TryFrom<(&types::PaymentsAuthorizeRouterData, MinorUnit)> for PaymentIntent }; (charges, None) } - Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(_))| - None => (None, item.connector_customer.to_owned().map(Secret::new)), + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(_)) | None => { + (None, item.connector_customer.to_owned().map(Secret::new)) + } }; Ok(Self { diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index 93618a92121e..4f935c5b6b18 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -6248,11 +6248,15 @@ pub fn validate_platform_fees_for_marketplace( ) -> Result<(), errors::ApiErrorResponse> { if let Some(split_payment) = split_payments { let (field_name, split_amount_i64) = match split_payment { - common_types::payments::SplitPaymentsRequest::StripeSplitPayment(stripe_split_payment) => ( + common_types::payments::SplitPaymentsRequest::StripeSplitPayment( + stripe_split_payment, + ) => ( "split_payments.stripe_split_payment.application_fees", stripe_split_payment.application_fees.get_amount_as_i64(), ), - common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_payment) => ( + common_types::payments::SplitPaymentsRequest::AdyenSplitPayment( + adyen_split_payment, + ) => ( "split_payments.adyen_split_payment.split_amount", adyen_split_payment.split_amount.get_amount_as_i64(), ), @@ -6266,23 +6270,19 @@ pub fn validate_platform_fees_for_marketplace( fn validate_split_amount( amount: api::Amount, split_amount_i64: i64, - field_name: &'static str , -) -> Result<(), errors::ApiErrorResponse> { + field_name: &'static str, +) -> Result<(), errors::ApiErrorResponse> { match amount { api::Amount::Zero => { if split_amount_i64 != 0 { - return Err(errors::ApiErrorResponse::InvalidDataValue { - field_name, - }); + return Err(errors::ApiErrorResponse::InvalidDataValue { field_name }); } } api::Amount::Value(amount) => { if split_amount_i64 > amount.into() { - return ErPr(errors::ApiErrorResponse::InvalidDataValue { - field_name, - }); + return ErPr(errors::ApiErrorResponse::InvalidDataValue { field_name }); } } } Ok(()) -} \ No newline at end of file +} From abdab2e01c8bd0661a5bd28d0b04c718365e0f00 Mon Sep 17 00:00:00 2001 From: AkshayaFoiger Date: Thu, 9 Jan 2025 16:34:48 +0530 Subject: [PATCH 03/21] refactor(core): add adyen split request and response --- crates/api_models/src/payments.rs | 23 +++++++++++-------- crates/common_types/src/payments.rs | 15 +++++++----- crates/router/src/connector/stripe.rs | 6 ++--- .../src/connector/stripe/transformers.rs | 5 ++-- crates/router/src/connector/utils.rs | 5 ++++ .../router/src/core/payments/transformers.rs | 2 +- 6 files changed, 34 insertions(+), 22 deletions(-) diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index f78211e9d013..d057cc4ff052 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -5011,15 +5011,20 @@ pub struct StripeSplitPaymentsResponse { /// Fee information to be charged on the payment being collected via Adyen #[derive(Setter, Clone, Debug, PartialEq, serde::Serialize, ToSchema)] -pub struct AdyenSplitPaymentResponse { - /// Unique Identifier for the split item - pub charge_id: String, - /// The amount of the split item. +pub struct AdyenSplitPaymentsResponse { + /// The amount of the split item #[schema(value_type = i64, example = 6540)] - pub split_amount: MinorUnit, - /// The currency of the split item. - #[schema(example = "USD", value_type = Currency)] - pub split_currency: Option, + pub amount: MinorUnit, + /// Defines type of split item + #[schema(value_type = AdyenSplitType, example = "balance_account")] + pub split_type: enums::AdyenSplitType, + /// The unique identifier of the account to which the split amount is allocated. + pub account: Option, + /// Unique Identifier for the split item + pub reference: Option, + /// Description for the part of the payment that will be allocated to the specified account. + pub description: Option, + } #[derive(Clone, Debug, PartialEq, serde::Serialize, ToSchema)] @@ -5028,7 +5033,7 @@ pub enum SplitPaymentsResponse { /// StripeSplitPaymentsResponse StripeSplitPayment(StripeSplitPaymentsResponse), /// AdyenSplitPaymentsResponse - AdyenSplitPayment(AdyenSplitPaymentResponse), + AdyenSplitPayment(AdyenSplitPaymentsResponse), } /// Details of external authentication diff --git a/crates/common_types/src/payments.rs b/crates/common_types/src/payments.rs index 5ad9f23de520..6bbca12831f0 100644 --- a/crates/common_types/src/payments.rs +++ b/crates/common_types/src/payments.rs @@ -48,15 +48,18 @@ impl_to_sql_from_sql_json!(StripeSplitPaymentRequest); #[serde(deny_unknown_fields)] /// Fee information for Split Payments to be charged on the payment being collected for Adyen pub struct AdyenSplitPaymentRequest { - /// The unique identifier of the account to which the split amount is booked - pub account: String, - /// The amount of the split item. + + /// The amount of the split item #[schema(value_type = i64, example = 6540)] - pub split_amount: MinorUnit, - /// Defines the part of the payment that one wants to book to the specified account. + pub amount: MinorUnit, + /// Defines type of split item #[schema(value_type = AdyenSplitType, example = "balance_account")] pub split_type: enums::AdyenSplitType, + /// The unique identifier of the account to which the split amount is allocated. + pub account: Option, /// Unique Identifier for the split item - pub charge_id: String, + pub reference: Option, + /// Description for the part of the payment that will be allocated to the specified account. + pub description: Option, } impl_to_sql_from_sql_json!(AdyenSplitPaymentRequest); diff --git a/crates/router/src/connector/stripe.rs b/crates/router/src/connector/stripe.rs index 909a5ff7ab38..c7f07dbd5af0 100644 --- a/crates/router/src/connector/stripe.rs +++ b/crates/router/src/connector/stripe.rs @@ -777,7 +777,7 @@ impl &mut header, ); } - common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(_) => (), + common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(_) => todo!(), //todooo } } Ok(header) @@ -963,8 +963,8 @@ impl )]; header.append(&mut customer_account_header); } - } - _ => (), + }, + common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(_) => todo!(), //todooo } } Ok(header) diff --git a/crates/router/src/connector/stripe/transformers.rs b/crates/router/src/connector/stripe/transformers.rs index af87ad6e1c8a..4d169bfebf18 100644 --- a/crates/router/src/connector/stripe/transformers.rs +++ b/crates/router/src/connector/stripe/transformers.rs @@ -1953,9 +1953,8 @@ impl TryFrom<(&types::PaymentsAuthorizeRouterData, MinorUnit)> for PaymentIntent }; (charges, None) } - Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(_)) | None => { - (None, item.connector_customer.to_owned().map(Secret::new)) - } + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(_)) => todo!(), //todooo + None => (None, item.connector_customer.to_owned().map(Secret::new)), }; Ok(Self { diff --git a/crates/router/src/connector/utils.rs b/crates/router/src/connector/utils.rs index 171f19bc70ab..701dc7552d7a 100644 --- a/crates/router/src/connector/utils.rs +++ b/crates/router/src/connector/utils.rs @@ -818,6 +818,7 @@ pub trait PaymentsAuthorizeRequestData { fn get_metadata_as_object(&self) -> Option; fn get_authentication_data(&self) -> Result; fn get_connector_mandate_request_reference_id(&self) -> Result; + fn get_split_payment_request(&self) -> Option<&common_types::payments::SplitPaymentsRequest>; } pub trait PaymentMethodTokenizationRequestData { @@ -1021,6 +1022,10 @@ impl PaymentsAuthorizeRequestData for types::PaymentsAuthorizeData { }) .ok_or_else(missing_field_err("connector_mandate_request_reference_id")) } + + fn get_split_payment_request(&self) -> Option<&common_types::payments::SplitPaymentsRequest> { + self.split_payments.as_ref() + } } pub trait ConnectorCustomerData { diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index 94c529231a1b..70ef1487ae09 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -2134,7 +2134,7 @@ where }, ), ), - common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(_) => None, + common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_payment) => todo!(), //todoooo }, }; From cedec57fb1e7b219f8df7dd3e7aeb540dc486fa6 Mon Sep 17 00:00:00 2001 From: "hyperswitch-bot[bot]" <148525504+hyperswitch-bot[bot]@users.noreply.github.com> Date: Thu, 9 Jan 2025 11:06:09 +0000 Subject: [PATCH 04/21] chore: run formatter --- crates/api_models/src/payments.rs | 1 - crates/common_types/src/payments.rs | 1 - crates/router/src/connector/stripe.rs | 4 ++-- crates/router/src/core/payments/transformers.rs | 4 +++- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index d057cc4ff052..7dc9cd7907d7 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -5024,7 +5024,6 @@ pub struct AdyenSplitPaymentsResponse { pub reference: Option, /// Description for the part of the payment that will be allocated to the specified account. pub description: Option, - } #[derive(Clone, Debug, PartialEq, serde::Serialize, ToSchema)] diff --git a/crates/common_types/src/payments.rs b/crates/common_types/src/payments.rs index 6bbca12831f0..3de9acf52b07 100644 --- a/crates/common_types/src/payments.rs +++ b/crates/common_types/src/payments.rs @@ -48,7 +48,6 @@ impl_to_sql_from_sql_json!(StripeSplitPaymentRequest); #[serde(deny_unknown_fields)] /// Fee information for Split Payments to be charged on the payment being collected for Adyen pub struct AdyenSplitPaymentRequest { - /// The amount of the split item #[schema(value_type = i64, example = 6540)] pub amount: MinorUnit, diff --git a/crates/router/src/connector/stripe.rs b/crates/router/src/connector/stripe.rs index c7f07dbd5af0..a96e90919aff 100644 --- a/crates/router/src/connector/stripe.rs +++ b/crates/router/src/connector/stripe.rs @@ -963,8 +963,8 @@ impl )]; header.append(&mut customer_account_header); } - }, - common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(_) => todo!(), //todooo + } + common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(_) => todo!(), //todooo } } Ok(header) diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index 70ef1487ae09..f94dc49ec9ef 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -2134,7 +2134,9 @@ where }, ), ), - common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_payment) => todo!(), //todoooo + common_types::payments::SplitPaymentsRequest::AdyenSplitPayment( + adyen_split_payment, + ) => todo!(), //todoooo }, }; From fda25c76ef29d9ab9c0925f8f409e303d700632a Mon Sep 17 00:00:00 2001 From: AkshayaFoiger Date: Thu, 9 Jan 2025 16:39:29 +0530 Subject: [PATCH 05/21] chore: undo get_split_payment_request() --- crates/router/src/connector/utils.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/crates/router/src/connector/utils.rs b/crates/router/src/connector/utils.rs index 701dc7552d7a..171f19bc70ab 100644 --- a/crates/router/src/connector/utils.rs +++ b/crates/router/src/connector/utils.rs @@ -818,7 +818,6 @@ pub trait PaymentsAuthorizeRequestData { fn get_metadata_as_object(&self) -> Option; fn get_authentication_data(&self) -> Result; fn get_connector_mandate_request_reference_id(&self) -> Result; - fn get_split_payment_request(&self) -> Option<&common_types::payments::SplitPaymentsRequest>; } pub trait PaymentMethodTokenizationRequestData { @@ -1022,10 +1021,6 @@ impl PaymentsAuthorizeRequestData for types::PaymentsAuthorizeData { }) .ok_or_else(missing_field_err("connector_mandate_request_reference_id")) } - - fn get_split_payment_request(&self) -> Option<&common_types::payments::SplitPaymentsRequest> { - self.split_payments.as_ref() - } } pub trait ConnectorCustomerData { From 0e0f4998052c866237018cdde2ecc2f7b76af41f Mon Sep 17 00:00:00 2001 From: AkshayaFoiger Date: Mon, 13 Jan 2025 14:13:51 +0530 Subject: [PATCH 06/21] feat(router): add adyen split response and request types --- crates/api_models/src/payments.rs | 18 +-- crates/common_enums/src/enums.rs | 4 - crates/common_types/src/payments.rs | 22 ++- crates/openapi/src/openapi.rs | 3 +- crates/openapi/src/openapi_v2.rs | 3 +- crates/router/src/core/payments/helpers.rs | 139 +++++++++++++----- .../payments/operations/payment_create.rs | 2 +- 7 files changed, 132 insertions(+), 59 deletions(-) diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index 7dc9cd7907d7..89ead4167925 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -5009,21 +5009,13 @@ pub struct StripeSplitPaymentsResponse { pub transfer_account_id: String, } -/// Fee information to be charged on the payment being collected via Adyen #[derive(Setter, Clone, Debug, PartialEq, serde::Serialize, ToSchema)] +/// Fee information to be charged on the payment being collected via Adyen pub struct AdyenSplitPaymentsResponse { - /// The amount of the split item - #[schema(value_type = i64, example = 6540)] - pub amount: MinorUnit, - /// Defines type of split item - #[schema(value_type = AdyenSplitType, example = "balance_account")] - pub split_type: enums::AdyenSplitType, - /// The unique identifier of the account to which the split amount is allocated. - pub account: Option, - /// Unique Identifier for the split item - pub reference: Option, - /// Description for the part of the payment that will be allocated to the specified account. - pub description: Option, + /// The store identifier + pub store_id: Option, + /// Data for the split items + pub split_items: Vec, } #[derive(Clone, Debug, PartialEq, serde::Serialize, ToSchema)] diff --git a/crates/common_enums/src/enums.rs b/crates/common_enums/src/enums.rs index a45eb3278be6..89682e2e5c61 100644 --- a/crates/common_enums/src/enums.rs +++ b/crates/common_enums/src/enums.rs @@ -3624,7 +3624,6 @@ pub enum FeatureStatus { strum::Display, strum::EnumString, ToSchema, - Default, )] #[strum(serialize_all = "snake_case")] #[serde(rename_all = "snake_case")] @@ -3651,7 +3650,4 @@ pub enum AdyenSplitType { TopUp, /// The value-added tax charged on the payment, booked to your platforms liable balance account. Vat, - /// In very specific use cases, allows you to book the specified amount to the specified account. - #[default] - Default, } diff --git a/crates/common_types/src/payments.rs b/crates/common_types/src/payments.rs index 3de9acf52b07..83df36d7d9ab 100644 --- a/crates/common_types/src/payments.rs +++ b/crates/common_types/src/payments.rs @@ -17,7 +17,7 @@ pub enum SplitPaymentsRequest { /// StripeSplitPayment StripeSplitPayment(StripeSplitPaymentRequest), /// AdyenSplitPayment - AdyenSplitPayment(AdyenSplitPaymentRequest), + AdyenSplitPayment(AdyenSplitPaymentsRequest), } impl_to_sql_from_sql_json!(SplitPaymentsRequest); @@ -47,10 +47,24 @@ impl_to_sql_from_sql_json!(StripeSplitPaymentRequest); #[diesel(sql_type = Jsonb)] #[serde(deny_unknown_fields)] /// Fee information for Split Payments to be charged on the payment being collected for Adyen -pub struct AdyenSplitPaymentRequest { +pub struct AdyenSplitPaymentsRequest { + /// The store identifier + pub store_id: Option, + /// Data for the split items + pub split_items: Vec, +} +impl_to_sql_from_sql_json!(AdyenSplitPaymentsRequest); + +#[derive( + Serialize, Deserialize, Debug, Clone, PartialEq, Eq, FromSqlRow, AsExpression, ToSchema, +)] +#[diesel(sql_type = Jsonb)] +#[serde(deny_unknown_fields)] +/// Data for the split items +pub struct AdyenSplitItem { /// The amount of the split item #[schema(value_type = i64, example = 6540)] - pub amount: MinorUnit, + pub amount: Option, /// Defines type of split item #[schema(value_type = AdyenSplitType, example = "balance_account")] pub split_type: enums::AdyenSplitType, @@ -61,4 +75,4 @@ pub struct AdyenSplitPaymentRequest { /// Description for the part of the payment that will be allocated to the specified account. pub description: Option, } -impl_to_sql_from_sql_json!(AdyenSplitPaymentRequest); +impl_to_sql_from_sql_json!(AdyenSplitItem); diff --git a/crates/openapi/src/openapi.rs b/crates/openapi/src/openapi.rs index b17e0a56c28e..0abb7fffbab6 100644 --- a/crates/openapi/src/openapi.rs +++ b/crates/openapi/src/openapi.rs @@ -216,7 +216,8 @@ Never share your secret api keys. Keep them guarded and secure. common_utils::payout_method_utils::VenmoAdditionalData, common_types::payments::SplitPaymentsRequest, common_types::payments::StripeSplitPaymentRequest, - common_types::payments::AdyenSplitPaymentRequest, + common_types::payments::AdyenSplitPaymentsRequest, + common_types::payments::AdyenSplitItem, common_utils::types::ChargeRefunds, common_types::refunds::SplitRefund, common_types::refunds::StripeSplitRefundRequest, diff --git a/crates/openapi/src/openapi_v2.rs b/crates/openapi/src/openapi_v2.rs index d2dfea4a06a9..8189504350db 100644 --- a/crates/openapi/src/openapi_v2.rs +++ b/crates/openapi/src/openapi_v2.rs @@ -159,7 +159,8 @@ Never share your secret api keys. Keep them guarded and secure. common_utils::payout_method_utils::VenmoAdditionalData, common_types::payments::SplitPaymentsRequest, common_types::payments::StripeSplitPaymentRequest, - common_types::payments::AdyenSplitPaymentRequest, + common_types::payments::AdyenSplitPaymentsRequest, + common_types::payments::AdyenSplitItem, common_types::refunds::StripeSplitRefundRequest, common_utils::types::ChargeRefunds, common_types::payment_methods::PaymentMethodsEnabled, diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index 4f935c5b6b18..9e2dc14f3d9a 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -6242,47 +6242,116 @@ pub async fn validate_merchant_connector_ids_in_connector_mandate_details( Ok(()) } -pub fn validate_platform_fees_for_marketplace( +pub fn validate_platform_request_for_marketplace( amount: api::Amount, split_payments: Option, ) -> Result<(), errors::ApiErrorResponse> { - if let Some(split_payment) = split_payments { - let (field_name, split_amount_i64) = match split_payment { - common_types::payments::SplitPaymentsRequest::StripeSplitPayment( - stripe_split_payment, - ) => ( - "split_payments.stripe_split_payment.application_fees", - stripe_split_payment.application_fees.get_amount_as_i64(), - ), - common_types::payments::SplitPaymentsRequest::AdyenSplitPayment( - adyen_split_payment, - ) => ( - "split_payments.adyen_split_payment.split_amount", - adyen_split_payment.split_amount.get_amount_as_i64(), - ), - }; - - validate_split_amount(amount, split_amount_i64, field_name)?; - } - Ok(()) -} - -fn validate_split_amount( - amount: api::Amount, - split_amount_i64: i64, - field_name: &'static str, -) -> Result<(), errors::ApiErrorResponse> { - match amount { - api::Amount::Zero => { - if split_amount_i64 != 0 { - return Err(errors::ApiErrorResponse::InvalidDataValue { field_name }); + match split_payments { + Some(common_types::payments::SplitPaymentsRequest::StripeSplitPayment( + stripe_split_payment, + )) => match amount { + api::Amount::Zero => { + if stripe_split_payment.application_fees.get_amount_as_i64() != 0 { + return Err(errors::ApiErrorResponse::InvalidDataValue { + field_name: "split_payments.stripe_split_payment.application_fees", + }); + } } - } - api::Amount::Value(amount) => { - if split_amount_i64 > amount.into() { - return ErPr(errors::ApiErrorResponse::InvalidDataValue { field_name }); + api::Amount::Value(amount) => { + if stripe_split_payment.application_fees.get_amount_as_i64() > amount.into() { + return Err(errors::ApiErrorResponse::InvalidDataValue { + field_name: "split_payments.stripe_split_payment.application_fees", + }); + } } + }, + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment( + adyen_split_payment, + )) => { + let total_split_amount = adyen_split_payment + .split_items + .iter() + .map(|split_item| split_item.amount.unwrap_or(0).get_amount_as_i64()) + .sum(); + match amount { + api::Amount::Zero => { + if total_split_amount != 0 { + return Err(errors::ApiErrorResponse::InvalidDataValue { + field_name: "split_payments.adyen_split_payment.application_fees", + }); + } + } + api::Amount::Value(amount) => { + if total_split_amount != amount.into() { + return Err(errors::ApiErrorResponse::PreconditionFailed { + message: "split_payments.adyen_split_payment.application_fees" + .to_string(), + }); + } + } + }; + adyen_split_payment + .split_items + .iter() + .try_for_each(|split_item| { + match split_item.split_type { + common_enums::AdyenSplitType::BalanceAccount => { + if split_item.account.is_none() { + return Err(errors::ApiErrorResponse::MissingRequiredField { + field_name: + "split_payments.adyen_split_payment.split_items.account", + }); + } + if split_item.reference.is_none() { + return Err(errors::ApiErrorResponse::MissingRequiredField { + field_name: + "split_payments.adyen_split_payment.split_items.reference", + }); + } + } + common_enums::AdyenSplitType::Commission => { + if split_item.amount.is_none() { + return Err(errors::ApiErrorResponse::MissingRequiredField { + field_name: "split_payments.adyen_split_payment.split_items.amount", + }); + } + } + enums::AdyenSplitType::Vat => { + if split_item.amount.is_none() { + return Err(errors::ApiErrorResponse::MissingRequiredField { + field_name: "split_payments.adyen_split_payment.split_items.amount", + }); + } + } + enums::AdyenSplitType::TopUp => { + if split_item.amount.is_none() { + return Err(errors::ApiErrorResponse::MissingRequiredField { + field_name: "split_payments.adyen_split_payment.split_items.amount", + }); + } + if split_item.account.is_none() { + return Err(errors::ApiErrorResponse::MissingRequiredField { + field_name: "split_payments.adyen_split_payment.split_items.amount", + }); + } + if adyen_split_payment.store_id.is_some() { + return Err(errors::ApiErrorResponse::PreconditionFailed { + field_name: "Topup split is not available via Adyen plaform", + }); + } + } + enums::AdyenSplitType::AcquiringFees + | enums::AdyenSplitType::PaymentFee + | enums::AdyenSplitType::AdyenFees + | enums::AdyenSplitType::AdyenCommission + | enums::AdyenSplitType::AdyenMarkup + | enums::AdyenSplitType::Interchange + | enums::AdyenSplitType::SchemeFee => (), + } + }) + } + None => Ok(()), } Ok(()) } diff --git a/crates/router/src/core/payments/operations/payment_create.rs b/crates/router/src/core/payments/operations/payment_create.rs index b7b3420987d1..fad2eba2e63f 100644 --- a/crates/router/src/core/payments/operations/payment_create.rs +++ b/crates/router/src/core/payments/operations/payment_create.rs @@ -1029,7 +1029,7 @@ impl ValidateRequest Date: Mon, 13 Jan 2025 08:50:55 +0000 Subject: [PATCH 07/21] chore: run formatter --- crates/router/src/core/payments/helpers.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index 9e2dc14f3d9a..7a44b730c4fa 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -6291,10 +6291,9 @@ pub fn validate_platform_request_for_marketplace( } }; adyen_split_payment - .split_items - .iter() - .try_for_each(|split_item| { - match split_item.split_type { + .split_items + .iter() + .try_for_each(|split_item| match split_item.split_type { common_enums::AdyenSplitType::BalanceAccount => { if split_item.account.is_none() { return Err(errors::ApiErrorResponse::MissingRequiredField { @@ -6347,9 +6346,7 @@ pub fn validate_platform_request_for_marketplace( | enums::AdyenSplitType::AdyenMarkup | enums::AdyenSplitType::Interchange | enums::AdyenSplitType::SchemeFee => (), - } - }) - + }) } None => Ok(()), } From 5af13b04aa334412e442c0280ddab8a4aba7a8b0 Mon Sep 17 00:00:00 2001 From: AkshayaFoiger Date: Mon, 13 Jan 2025 17:18:56 +0530 Subject: [PATCH 08/21] refactor(router): refactor charge_id in transactional response --- connector-template/transformers.rs | 2 +- .../src/connectors/airwallex/transformers.rs | 4 +- .../src/connectors/amazonpay/transformers.rs | 2 +- .../src/connectors/bambora/transformers.rs | 12 +- .../connectors/bamboraapac/transformers.rs | 8 +- .../src/connectors/billwerk/transformers.rs | 2 +- .../src/connectors/bitpay/transformers.rs | 2 +- .../src/connectors/bluesnap.rs | 2 +- .../src/connectors/bluesnap/transformers.rs | 2 +- .../src/connectors/boku/transformers.rs | 18 +-- .../src/connectors/cashtocode/transformers.rs | 4 +- .../src/connectors/coinbase/transformers.rs | 2 +- .../src/connectors/cryptopay/transformers.rs | 2 +- .../src/connectors/datatrans/transformers.rs | 4 +- .../connectors/deutschebank/transformers.rs | 8 +- .../connectors/digitalvirgo/transformers.rs | 4 +- .../src/connectors/dlocal/transformers.rs | 8 +- .../src/connectors/elavon/transformers.rs | 6 +- .../src/connectors/fiserv/transformers.rs | 4 +- .../src/connectors/fiservemea/transformers.rs | 2 +- .../src/connectors/fiuu/transformers.rs | 18 +-- .../src/connectors/forte/transformers.rs | 8 +- .../src/connectors/globepay/transformers.rs | 4 +- .../src/connectors/gocardless/transformers.rs | 6 +- .../src/connectors/helcim/transformers.rs | 10 +- .../src/connectors/inespay/transformers.rs | 2 +- .../src/connectors/jpmorgan/transformers.rs | 8 +- .../src/connectors/mollie/transformers.rs | 2 +- .../connectors/multisafepay/transformers.rs | 2 +- .../src/connectors/nexinets/transformers.rs | 4 +- .../src/connectors/nexixpay/transformers.rs | 14 +- .../src/connectors/nomupay/transformers.rs | 2 +- .../src/connectors/novalnet/transformers.rs | 8 +- .../src/connectors/paybox/transformers.rs | 10 +- .../src/connectors/payeezy/transformers.rs | 2 +- .../src/connectors/payu/transformers.rs | 8 +- .../src/connectors/placetopay/transformers.rs | 2 +- .../src/connectors/powertranz/transformers.rs | 2 +- .../src/connectors/prophetpay/transformers.rs | 8 +- .../src/connectors/rapyd/transformers.rs | 2 +- .../src/connectors/razorpay/transformers.rs | 4 +- .../src/connectors/redsys/transformers.rs | 2 +- .../src/connectors/shift4/transformers.rs | 8 +- .../src/connectors/square/transformers.rs | 2 +- .../src/connectors/stax/transformers.rs | 2 +- .../src/connectors/thunes/transformers.rs | 2 +- .../src/connectors/tsys/transformers.rs | 4 +- .../src/connectors/volt/transformers.rs | 6 +- .../src/connectors/worldline/transformers.rs | 4 +- .../src/connectors/worldpay.rs | 6 +- .../src/connectors/worldpay/transformers.rs | 2 +- .../src/connectors/xendit/transformers.rs | 2 +- .../src/connectors/zen/transformers.rs | 4 +- .../src/connectors/zsl/transformers.rs | 4 +- .../src/router_response_types.rs | 36 ++++- .../router/src/connector/aci/transformers.rs | 2 +- .../src/connector/adyen/transformers.rs | 18 +-- .../connector/authorizedotnet/transformers.rs | 8 +- .../connector/bankofamerica/transformers.rs | 8 +- .../src/connector/braintree/transformers.rs | 18 +-- .../src/connector/checkout/transformers.rs | 8 +- .../src/connector/cybersource/transformers.rs | 12 +- .../connector/dummyconnector/transformers.rs | 2 +- .../src/connector/globalpay/transformers.rs | 2 +- .../src/connector/iatapay/transformers.rs | 4 +- .../src/connector/itaubank/transformers.rs | 4 +- .../src/connector/klarna/transformers.rs | 10 +- .../src/connector/mifinity/transformers.rs | 10 +- .../router/src/connector/nmi/transformers.rs | 14 +- .../router/src/connector/noon/transformers.rs | 2 +- .../src/connector/nuvei/transformers.rs | 2 +- .../src/connector/opayo/transformers.rs | 2 +- .../src/connector/opennode/transformers.rs | 2 +- .../src/connector/payme/transformers.rs | 8 +- crates/router/src/connector/paypal.rs | 4 +- .../src/connector/paypal/transformers.rs | 20 +-- .../src/connector/plaid/transformers.rs | 4 +- .../src/connector/stripe/transformers.rs | 16 +-- .../src/connector/trustpay/transformers.rs | 10 +- .../src/connector/wellsfargo/transformers.rs | 8 +- .../wellsfargopayout/transformers.rs | 2 +- crates/router/src/core/payments/helpers.rs | 124 +++++++++--------- .../payments/operations/payment_response.rs | 4 +- crates/router/src/core/payments/retry.rs | 4 +- .../router/src/core/payments/transformers.rs | 4 +- crates/router/src/core/refunds.rs | 2 +- 86 files changed, 339 insertions(+), 307 deletions(-) diff --git a/connector-template/transformers.rs b/connector-template/transformers.rs index b508596cbc08..73e167d89fd6 100644 --- a/connector-template/transformers.rs +++ b/connector-template/transformers.rs @@ -138,7 +138,7 @@ impl TryFrom TryFrom TryFrom TryFrom TryFrom network_txn_id: None, connector_response_reference_id: Some(item.response.order_number.to_string()), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -593,7 +593,7 @@ impl network_txn_id: None, connector_response_reference_id: Some(item.response.order_number.to_string()), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -628,7 +628,7 @@ impl network_txn_id: None, connector_response_reference_id: Some(item.response.order_number.to_string()), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -663,7 +663,7 @@ impl network_txn_id: None, connector_response_reference_id: Some(item.response.order_number.to_string()), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) diff --git a/crates/hyperswitch_connectors/src/connectors/bamboraapac/transformers.rs b/crates/hyperswitch_connectors/src/connectors/bamboraapac/transformers.rs index f4399d105c5d..5996ba05834e 100644 --- a/crates/hyperswitch_connectors/src/connectors/bamboraapac/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/bamboraapac/transformers.rs @@ -313,7 +313,7 @@ impl network_txn_id: None, connector_response_reference_id: Some(connector_transaction_id), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -485,7 +485,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -631,7 +631,7 @@ impl network_txn_id: None, connector_response_reference_id: Some(connector_transaction_id), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -910,7 +910,7 @@ impl network_txn_id: None, connector_response_reference_id: Some(connector_transaction_id), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) diff --git a/crates/hyperswitch_connectors/src/connectors/billwerk/transformers.rs b/crates/hyperswitch_connectors/src/connectors/billwerk/transformers.rs index 05b9abae0515..9fe00bac046c 100644 --- a/crates/hyperswitch_connectors/src/connectors/billwerk/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/billwerk/transformers.rs @@ -291,7 +291,7 @@ impl TryFrom TryFrom TryFrom, } @@ -291,7 +291,7 @@ pub struct ChargeResponseData { #[serde(rename_all = "kebab-case")] pub struct SingleChargeResponseData { charge_status: String, - charge_id: String, + charges: String, } impl TryFrom> @@ -316,7 +316,7 @@ impl TryFrom> network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -344,7 +344,7 @@ fn get_authorize_response( }), }?; - Ok((status, response.charge_id, redirection_data)) + Ok((status, response.charges, redirection_data)) } fn get_psync_response( @@ -352,7 +352,7 @@ fn get_psync_response( ) -> Result<(enums::AttemptStatus, String, Option), errors::ConnectorError> { let status = get_response_status(response.charges.charge.charge_status); - Ok((status, response.charges.charge.charge_id, None)) + Ok((status, response.charges.charge.charges, None)) } // REFUND : @@ -363,7 +363,7 @@ pub struct BokuRefundRequest { merchant_id: Secret, merchant_request_id: String, merchant_refund_id: Secret, - charge_id: String, + charges: String, reason_code: String, } @@ -389,7 +389,7 @@ impl TryFrom<&BokuRouterData<&RefundsRouterData>> for BokuRefundRequest { merchant_id: auth_type.merchant_id, merchant_refund_id: Secret::new(item.router_data.request.refund_id.to_string()), merchant_request_id: Uuid::new_v4().to_string(), - charge_id: item + charges: item .router_data .request .connector_transaction_id @@ -404,7 +404,7 @@ impl TryFrom<&BokuRouterData<&RefundsRouterData>> for BokuRefundRequest { #[derive(Debug, Clone, Deserialize, Serialize)] #[serde(rename = "refund-charge-response")] pub struct RefundResponse { - charge_id: String, + charges: String, refund_status: String, } @@ -423,7 +423,7 @@ impl TryFrom> for RefundsRout ) -> Result { Ok(Self { response: Ok(RefundsResponseData { - connector_refund_id: item.response.charge_id, + connector_refund_id: item.response.charges, refund_status: get_refund_status(item.response.refund_status), }), ..item.data diff --git a/crates/hyperswitch_connectors/src/connectors/cashtocode/transformers.rs b/crates/hyperswitch_connectors/src/connectors/cashtocode/transformers.rs index 7a70d97a102c..c139bc1524db 100644 --- a/crates/hyperswitch_connectors/src/connectors/cashtocode/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/cashtocode/transformers.rs @@ -274,7 +274,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ) } @@ -307,7 +307,7 @@ impl TryFrom TryFrom .custom_id .or(Some(item.response.data.id)), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }) }; match amount_captured_in_minor_units { diff --git a/crates/hyperswitch_connectors/src/connectors/datatrans/transformers.rs b/crates/hyperswitch_connectors/src/connectors/datatrans/transformers.rs index 2ec76cb2937e..d999619d8c32 100644 --- a/crates/hyperswitch_connectors/src/connectors/datatrans/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/datatrans/transformers.rs @@ -289,7 +289,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }) } }; @@ -407,7 +407,7 @@ impl TryFrom> network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) diff --git a/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs b/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs index 85c5fc8dc816..08114e9ffa48 100644 --- a/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs @@ -351,7 +351,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }), @@ -402,7 +402,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -614,7 +614,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -687,7 +687,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) diff --git a/crates/hyperswitch_connectors/src/connectors/digitalvirgo/transformers.rs b/crates/hyperswitch_connectors/src/connectors/digitalvirgo/transformers.rs index a9408e4e1c52..f67271136f12 100644 --- a/crates/hyperswitch_connectors/src/connectors/digitalvirgo/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/digitalvirgo/transformers.rs @@ -167,7 +167,7 @@ impl TryFrom TryFrom TryFrom TryFrom TryFrom TryFrom network_txn_id: None, connector_response_reference_id: Some(response.ssl_txn_id.clone()), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }) } } @@ -391,7 +391,7 @@ impl TryFrom> for PaymentsSyn network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -450,7 +450,7 @@ impl TryFrom> network_txn_id: None, connector_response_reference_id: Some(response.ssl_txn_id.clone()), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }) } } diff --git a/crates/hyperswitch_connectors/src/connectors/fiserv/transformers.rs b/crates/hyperswitch_connectors/src/connectors/fiserv/transformers.rs index f4084525410e..d6e2cd54db7f 100644 --- a/crates/hyperswitch_connectors/src/connectors/fiserv/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/fiserv/transformers.rs @@ -385,7 +385,7 @@ impl TryFrom TryFrom TryFrom network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }), @@ -793,7 +793,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -849,7 +849,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }) }; Ok(Self { @@ -895,7 +895,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }) }; Self { @@ -914,7 +914,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }); Self { response, @@ -1185,7 +1185,7 @@ impl TryFrom> for PaymentsSy network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }; Ok(Self { status, @@ -1246,7 +1246,7 @@ impl TryFrom> for PaymentsSy network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }; Ok(Self { status, @@ -1415,7 +1415,7 @@ impl TryFrom> network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }; Ok(Self { status, @@ -1526,7 +1526,7 @@ impl TryFrom> network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }; Ok(Self { status, diff --git a/crates/hyperswitch_connectors/src/connectors/forte/transformers.rs b/crates/hyperswitch_connectors/src/connectors/forte/transformers.rs index 2583f47058bf..31265162ca09 100644 --- a/crates/hyperswitch_connectors/src/connectors/forte/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/forte/transformers.rs @@ -308,7 +308,7 @@ impl TryFrom TryFrom> network_txn_id: None, connector_response_reference_id: Some(item.response.transaction_id.to_string()), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), amount_captured: None, ..item.data @@ -488,7 +488,7 @@ impl TryFrom TryFrom TryFrom redirection_data: Box::new(None), mandate_reference: Box::new(mandate_reference), network_txn_id: None, - charge_id: None, + charges: None, }), status: enums::AttemptStatus::Charged, ..item.data @@ -685,7 +685,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -716,7 +716,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) diff --git a/crates/hyperswitch_connectors/src/connectors/helcim/transformers.rs b/crates/hyperswitch_connectors/src/connectors/helcim/transformers.rs index 4a8ddf68df9a..0a5453a49d04 100644 --- a/crates/hyperswitch_connectors/src/connectors/helcim/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/helcim/transformers.rs @@ -387,7 +387,7 @@ impl network_txn_id: None, connector_response_reference_id: item.response.invoice_number.clone(), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), status: enums::AttemptStatus::from(item.response), ..item.data @@ -438,7 +438,7 @@ impl network_txn_id: None, connector_response_reference_id: item.response.invoice_number.clone(), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), status: enums::AttemptStatus::from(item.response), ..item.data @@ -487,7 +487,7 @@ impl network_txn_id: None, connector_response_reference_id: item.response.invoice_number.clone(), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), status: enums::AttemptStatus::from(item.response), ..item.data @@ -567,7 +567,7 @@ impl network_txn_id: None, connector_response_reference_id: item.response.invoice_number.clone(), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), status: enums::AttemptStatus::from(item.response), ..item.data @@ -624,7 +624,7 @@ impl network_txn_id: None, connector_response_reference_id: item.response.invoice_number.clone(), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), status: enums::AttemptStatus::from(item.response), ..item.data diff --git a/crates/hyperswitch_connectors/src/connectors/inespay/transformers.rs b/crates/hyperswitch_connectors/src/connectors/inespay/transformers.rs index 296d76546c84..8940e2363630 100644 --- a/crates/hyperswitch_connectors/src/connectors/inespay/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/inespay/transformers.rs @@ -135,7 +135,7 @@ impl TryFrom TryFrom TryFrom network_txn_id: None, connector_response_reference_id: Some(item.response.transaction_id.clone()), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -711,7 +711,7 @@ impl network_txn_id: None, connector_response_reference_id: Some(item.response.transaction_id.clone()), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) diff --git a/crates/hyperswitch_connectors/src/connectors/mollie/transformers.rs b/crates/hyperswitch_connectors/src/connectors/mollie/transformers.rs index 5257df672f40..b546b47e1855 100644 --- a/crates/hyperswitch_connectors/src/connectors/mollie/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/mollie/transformers.rs @@ -513,7 +513,7 @@ impl TryFrom TryFrom TryFrom TryFrom network_txn_id: None, connector_response_reference_id: Some(item.response.operation.order_id), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -829,7 +829,7 @@ impl response_body.operation.order_id.clone(), ), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -848,7 +848,7 @@ impl mandate_response.operation.order_id.clone(), ), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }), @@ -971,7 +971,7 @@ impl network_txn_id: None, connector_response_reference_id: Some(item.response.operation.order_id), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -1143,7 +1143,7 @@ impl network_txn_id: None, connector_response_reference_id: Some(item.response.order_id.clone()), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -1201,7 +1201,7 @@ impl item.data.request.connector_transaction_id.clone(), ), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -1264,7 +1264,7 @@ impl item.data.request.connector_transaction_id.clone(), ), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) diff --git a/crates/hyperswitch_connectors/src/connectors/nomupay/transformers.rs b/crates/hyperswitch_connectors/src/connectors/nomupay/transformers.rs index bea8b607daea..93b38001576a 100644 --- a/crates/hyperswitch_connectors/src/connectors/nomupay/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/nomupay/transformers.rs @@ -135,7 +135,7 @@ impl TryFrom TryFrom network_txn_id: None, connector_response_reference_id: transaction_id.clone(), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -1087,7 +1087,7 @@ impl network_txn_id: None, connector_response_reference_id: transaction_id.clone(), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -1256,7 +1256,7 @@ impl network_txn_id: None, connector_response_reference_id: transaction_id.clone(), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) diff --git a/crates/hyperswitch_connectors/src/connectors/paybox/transformers.rs b/crates/hyperswitch_connectors/src/connectors/paybox/transformers.rs index effe6df28db2..2515f5e8109e 100644 --- a/crates/hyperswitch_connectors/src/connectors/paybox/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/paybox/transformers.rs @@ -699,7 +699,7 @@ impl TryFrom TryFrom TryFrom TryFrom network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }), diff --git a/crates/hyperswitch_connectors/src/connectors/payeezy/transformers.rs b/crates/hyperswitch_connectors/src/connectors/payeezy/transformers.rs index 49188803c4f6..8437b660a83c 100644 --- a/crates/hyperswitch_connectors/src/connectors/payeezy/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/payeezy/transformers.rs @@ -447,7 +447,7 @@ impl TryFrom TryFrom TryFrom TryFrom TryFrom TryFrom TryFrom network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -411,7 +411,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -459,7 +459,7 @@ impl TryFrom TryFrom TryFrom TryFrom TryFrom TryFrom> network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -806,7 +806,7 @@ impl TryFrom TryFrom TryFrom<&Shift4RouterData<&RefundsRouterData>> for Shift4RefundReques type Error = Error; fn try_from(item: &Shift4RouterData<&RefundsRouterData>) -> Result { Ok(Self { - charge_id: item.router_data.request.connector_transaction_id.clone(), + charges: item.router_data.request.connector_transaction_id.clone(), amount: item.amount.to_owned(), }) } diff --git a/crates/hyperswitch_connectors/src/connectors/square/transformers.rs b/crates/hyperswitch_connectors/src/connectors/square/transformers.rs index 5abc93b3f882..af91cefa37b8 100644 --- a/crates/hyperswitch_connectors/src/connectors/square/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/square/transformers.rs @@ -394,7 +394,7 @@ impl TryFrom TryFrom TryFrom PaymentsResponseDa network_txn_id: None, connector_response_reference_id: Some(connector_response.transaction_id), incremental_authorization_allowed: None, - charge_id: None, + charges: None, } } @@ -275,7 +275,7 @@ fn get_payments_sync_response( .clone(), ), incremental_authorization_allowed: None, - charge_id: None, + charges: None, } } diff --git a/crates/hyperswitch_connectors/src/connectors/volt/transformers.rs b/crates/hyperswitch_connectors/src/connectors/volt/transformers.rs index a0d349eaa984..868161952762 100644 --- a/crates/hyperswitch_connectors/src/connectors/volt/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/volt/transformers.rs @@ -289,7 +289,7 @@ impl TryFrom TryFrom TryFrom TryFrom> network_txn_id: None, connector_response_reference_id: Some(item.response.id), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -634,7 +634,7 @@ impl TryFrom for Wo network_txn_id: None, connector_response_reference_id: optional_correlation_id, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..data.clone() }) @@ -531,7 +531,7 @@ impl ConnectorIntegration for Wor network_txn_id: None, connector_response_reference_id: optional_correlation_id, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..data.clone() }) @@ -632,7 +632,7 @@ impl ConnectorIntegration fo network_txn_id: None, connector_response_reference_id: optional_correlation_id, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..data.clone() }) diff --git a/crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs b/crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs index ec23b520a200..d66b76ef939c 100644 --- a/crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs @@ -728,7 +728,7 @@ impl network_txn_id: None, connector_response_reference_id: optional_correlation_id.clone(), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), (Some(reason), _) => Err(ErrorResponse { code: worldpay_status.to_string(), diff --git a/crates/hyperswitch_connectors/src/connectors/xendit/transformers.rs b/crates/hyperswitch_connectors/src/connectors/xendit/transformers.rs index c9d4cd2583c2..422c34e37c11 100644 --- a/crates/hyperswitch_connectors/src/connectors/xendit/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/xendit/transformers.rs @@ -135,7 +135,7 @@ impl TryFrom TryFrom TryFrom TryFrom, connector_response_reference_id: Option, incremental_authorization_allowed: Option, - charge_id: Option, + charges: Option>, }, MultipleCaptureResponse { // pending_capture_id_list: Vec, @@ -163,7 +163,7 @@ impl PaymentsResponseData { network_txn_id: auth_network_txn_id, connector_response_reference_id: auth_connector_response_reference_id, incremental_authorization_allowed: auth_incremental_auth_allowed, - charge_id: auth_charge_id, + charges: auth_charges, }, Self::TransactionResponse { resource_id: capture_resource_id, @@ -173,7 +173,7 @@ impl PaymentsResponseData { network_txn_id: capture_network_txn_id, connector_response_reference_id: capture_connector_response_reference_id, incremental_authorization_allowed: capture_incremental_auth_allowed, - charge_id: capture_charge_id, + charges: capture_charges, }, ) => Ok(Self::TransactionResponse { resource_id: capture_resource_id.clone(), @@ -198,7 +198,7 @@ impl PaymentsResponseData { .or(auth_connector_response_reference_id.clone()), incremental_authorization_allowed: (*capture_incremental_auth_allowed) .or(*auth_incremental_auth_allowed), - charge_id: capture_charge_id.clone().or(auth_charge_id.clone()), + charges: auth_charges.clone().or(capture_charges.clone()), }), _ => Err(ApiErrorResponse::NotSupported { message: "Invalid Flow ".to_owned(), @@ -506,6 +506,34 @@ pub enum AuthenticationResponseData { }, } +#[derive(Debug, Clone)] +pub struct StripeChargeResponseData { + pub application_fee: MinorUnit, + pub charge_type: common_enums::StripeChargeType, + pub charge_id: Option, + pub transfer_account_id: Option, +} + +#[derive(Debug, Clone)] +pub struct AdyenChargeResponseData { + pub store_id: Option, + pub split_items: Vec, +} + +#[derive(Debug, Clone)] +pub struct AdyenSplitItemResponse { + pub amount: MinorUnit, + pub split_type: common_enums::AdyenSplitType, + pub refernce: Option, + pub account: Option, +} + +#[derive(Debug, Clone)] +pub enum ConnectorChargeResponseData { + Stripe(StripeChargeResponseData), + Adyen(AdyenChargeResponseData), +} + #[derive(Debug, Clone)] pub struct CompleteAuthorizeRedirectResponse { pub params: Option>, diff --git a/crates/router/src/connector/aci/transformers.rs b/crates/router/src/connector/aci/transformers.rs index 3e25799c02e6..0641fc2895cc 100644 --- a/crates/router/src/connector/aci/transformers.rs +++ b/crates/router/src/connector/aci/transformers.rs @@ -771,7 +771,7 @@ impl network_txn_id: None, connector_response_reference_id: Some(item.response.id), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) diff --git a/crates/router/src/connector/adyen/transformers.rs b/crates/router/src/connector/adyen/transformers.rs index aece1df65463..7d1e5077936d 100644 --- a/crates/router/src/connector/adyen/transformers.rs +++ b/crates/router/src/connector/adyen/transformers.rs @@ -3416,7 +3416,7 @@ impl TryFrom> network_txn_id: None, connector_response_reference_id: Some(item.response.reference), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -3451,7 +3451,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), payment_method_balance: Some(types::PaymentMethodBalance { currency: item.response.balance.currency, @@ -3521,7 +3521,7 @@ pub fn get_adyen_response( network_txn_id, connector_response_reference_id: Some(response.merchant_reference), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }; Ok((status, error, payments_response_data)) } @@ -3588,7 +3588,7 @@ pub fn get_webhook_response( network_txn_id: None, connector_response_reference_id: Some(response.merchant_reference_id), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }; Ok((status, error, payments_response_data)) } @@ -3664,7 +3664,7 @@ pub fn get_redirection_response( .clone() .or(response.psp_reference), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }; Ok((status, error, payments_response_data)) } @@ -3725,7 +3725,7 @@ pub fn get_present_to_shopper_response( .clone() .or(response.psp_reference), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }; Ok((status, error, payments_response_data)) } @@ -3785,7 +3785,7 @@ pub fn get_qr_code_response( .clone() .or(response.psp_reference), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }; Ok((status, error, payments_response_data)) } @@ -3828,7 +3828,7 @@ pub fn get_redirection_error_response( .clone() .or(response.psp_reference), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }; Ok((status, error, payments_response_data)) @@ -4195,7 +4195,7 @@ impl TryFrom> network_txn_id: None, connector_response_reference_id: Some(item.response.reference), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), amount_captured: Some(0), ..item.data diff --git a/crates/router/src/connector/authorizedotnet/transformers.rs b/crates/router/src/connector/authorizedotnet/transformers.rs index 9698b4ac5d83..0033aa636ad6 100644 --- a/crates/router/src/connector/authorizedotnet/transformers.rs +++ b/crates/router/src/connector/authorizedotnet/transformers.rs @@ -407,7 +407,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }), @@ -1142,7 +1142,7 @@ impl transaction_response.transaction_id.clone(), ), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), }, ..item.data @@ -1215,7 +1215,7 @@ impl transaction_response.transaction_id.clone(), ), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), }, ..item.data @@ -1540,7 +1540,7 @@ impl network_txn_id: None, connector_response_reference_id: Some(transaction.transaction_id.clone()), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), status: payment_status, ..item.data diff --git a/crates/router/src/connector/bankofamerica/transformers.rs b/crates/router/src/connector/bankofamerica/transformers.rs index 71cc006700e4..7132fd9233a1 100644 --- a/crates/router/src/connector/bankofamerica/transformers.rs +++ b/crates/router/src/connector/bankofamerica/transformers.rs @@ -426,7 +426,7 @@ impl .unwrap_or(info_response.id), ), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), }, connector_response, @@ -1532,7 +1532,7 @@ fn get_payment_response( .unwrap_or(info_response.id.clone()), ), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }) } } @@ -1845,7 +1845,7 @@ impl .map(|cref| cref.code) .unwrap_or(Some(item.response.id)), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), connector_response, ..item.data @@ -1864,7 +1864,7 @@ impl network_txn_id: None, connector_response_reference_id: Some(item.response.id), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }), diff --git a/crates/router/src/connector/braintree/transformers.rs b/crates/router/src/connector/braintree/transformers.rs index 00624ce0f9b1..44fb39feb5a2 100644 --- a/crates/router/src/connector/braintree/transformers.rs +++ b/crates/router/src/connector/braintree/transformers.rs @@ -450,7 +450,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }) }; Ok(Self { @@ -473,7 +473,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }), @@ -626,7 +626,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }) }; Ok(Self { @@ -649,7 +649,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }), @@ -709,7 +709,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }) }; Ok(Self { @@ -774,7 +774,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }) }; Ok(Self { @@ -1282,7 +1282,7 @@ impl TryFrom> network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }) }; Ok(Self { @@ -1392,7 +1392,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }) }; Ok(Self { @@ -1497,7 +1497,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }) }; Ok(Self { diff --git a/crates/router/src/connector/checkout/transformers.rs b/crates/router/src/connector/checkout/transformers.rs index cd758fffb690..da6897b9adf4 100644 --- a/crates/router/src/connector/checkout/transformers.rs +++ b/crates/router/src/connector/checkout/transformers.rs @@ -700,7 +700,7 @@ impl TryFrom> item.response.reference.unwrap_or(item.response.id), ), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }; Ok(Self { status, @@ -753,7 +753,7 @@ impl TryFrom> item.response.reference.unwrap_or(item.response.id), ), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }; Ok(Self { status, @@ -829,7 +829,7 @@ impl TryFrom> network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), status: response.into(), ..item.data @@ -930,7 +930,7 @@ impl TryFrom> network_txn_id: None, connector_response_reference_id: item.response.reference, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), status, amount_captured, diff --git a/crates/router/src/connector/cybersource/transformers.rs b/crates/router/src/connector/cybersource/transformers.rs index 7ce98d3d5a34..f6bb721a557a 100644 --- a/crates/router/src/connector/cybersource/transformers.rs +++ b/crates/router/src/connector/cybersource/transformers.rs @@ -2575,7 +2575,7 @@ fn get_payment_response( .unwrap_or(info_response.id.clone()), ), incremental_authorization_allowed, - charge_id: None, + charges: None, }) } } @@ -2672,7 +2672,7 @@ impl .unwrap_or(info_response.id.clone()), ), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }), @@ -3080,7 +3080,7 @@ impl network_txn_id: None, connector_response_reference_id, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -3337,7 +3337,7 @@ impl incremental_authorization_allowed: Some( mandate_status == enums::AttemptStatus::Authorized, ), - charge_id: None, + charges: None, }), }, connector_response, @@ -3466,7 +3466,7 @@ impl .map(|cref| cref.code) .unwrap_or(Some(item.response.id)), incremental_authorization_allowed, - charge_id: None, + charges: None, }), ..item.data }) @@ -3484,7 +3484,7 @@ impl network_txn_id: None, connector_response_reference_id: Some(item.response.id), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }), diff --git a/crates/router/src/connector/dummyconnector/transformers.rs b/crates/router/src/connector/dummyconnector/transformers.rs index 79caa3d0a767..9d745ca19786 100644 --- a/crates/router/src/connector/dummyconnector/transformers.rs +++ b/crates/router/src/connector/dummyconnector/transformers.rs @@ -259,7 +259,7 @@ impl TryFrom types::PaymentsResponseData::TransactionResponse { @@ -400,7 +400,7 @@ fn get_iatpay_response( network_txn_id: None, connector_response_reference_id: connector_response_reference_id.clone(), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }, }; diff --git a/crates/router/src/connector/itaubank/transformers.rs b/crates/router/src/connector/itaubank/transformers.rs index 127f8526afe4..9d38044f0fe9 100644 --- a/crates/router/src/connector/itaubank/transformers.rs +++ b/crates/router/src/connector/itaubank/transformers.rs @@ -287,7 +287,7 @@ impl network_txn_id: None, connector_response_reference_id: Some(item.response.txid), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -375,7 +375,7 @@ impl network_txn_id: None, connector_response_reference_id: Some(item.response.txid), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) diff --git a/crates/router/src/connector/klarna/transformers.rs b/crates/router/src/connector/klarna/transformers.rs index 0826b0f2665b..51766cb2a2d8 100644 --- a/crates/router/src/connector/klarna/transformers.rs +++ b/crates/router/src/connector/klarna/transformers.rs @@ -389,7 +389,7 @@ impl TryFrom> network_txn_id: None, connector_response_reference_id: Some(response.order_id.clone()), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), status: enums::AttemptStatus::foreign_from(( response.fraud_status.clone(), @@ -412,7 +412,7 @@ impl TryFrom> network_txn_id: None, connector_response_reference_id: Some(response.order_id.clone()), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), status: enums::AttemptStatus::foreign_from(( response.status.clone(), @@ -575,7 +575,7 @@ impl .klarna_reference .or(Some(response.order_id.clone())), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }), @@ -594,7 +594,7 @@ impl network_txn_id: None, connector_response_reference_id: Some(response.order_id.clone()), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }), @@ -672,7 +672,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), status, ..item.data diff --git a/crates/router/src/connector/mifinity/transformers.rs b/crates/router/src/connector/mifinity/transformers.rs index 1e2c420c767b..e07354d18713 100644 --- a/crates/router/src/connector/mifinity/transformers.rs +++ b/crates/router/src/connector/mifinity/transformers.rs @@ -268,7 +268,7 @@ impl network_txn_id: None, connector_response_reference_id: Some(trace_id), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -283,7 +283,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }), @@ -352,7 +352,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -367,7 +367,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }), @@ -383,7 +383,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }), diff --git a/crates/router/src/connector/nmi/transformers.rs b/crates/router/src/connector/nmi/transformers.rs index 4c33f0200172..87e067cbbf67 100644 --- a/crates/router/src/connector/nmi/transformers.rs +++ b/crates/router/src/connector/nmi/transformers.rs @@ -212,7 +212,7 @@ impl network_txn_id: None, connector_response_reference_id: Some(item.response.transactionid), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), enums::AttemptStatus::AuthenticationPending, ), @@ -366,7 +366,7 @@ impl network_txn_id: None, connector_response_reference_id: Some(item.response.orderid), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), if let Some(diesel_models::enums::CaptureMethod::Automatic) = item.data.request.capture_method @@ -750,7 +750,7 @@ impl network_txn_id: None, connector_response_reference_id: Some(item.response.orderid), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), enums::AttemptStatus::CaptureInitiated, ), @@ -845,7 +845,7 @@ impl network_txn_id: None, connector_response_reference_id: Some(item.response.orderid), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), enums::AttemptStatus::Charged, ), @@ -902,7 +902,7 @@ impl TryFrom> network_txn_id: None, connector_response_reference_id: Some(item.response.orderid), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), if let Some(diesel_models::enums::CaptureMethod::Automatic) = item.data.request.capture_method @@ -953,7 +953,7 @@ impl network_txn_id: None, connector_response_reference_id: Some(item.response.orderid), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), enums::AttemptStatus::VoidInitiated, ), @@ -1004,7 +1004,7 @@ impl TryFrom network_txn_id: None, connector_response_reference_id, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }) } }, diff --git a/crates/router/src/connector/nuvei/transformers.rs b/crates/router/src/connector/nuvei/transformers.rs index a4195655ed38..aea111a992e7 100644 --- a/crates/router/src/connector/nuvei/transformers.rs +++ b/crates/router/src/connector/nuvei/transformers.rs @@ -1627,7 +1627,7 @@ where network_txn_id: None, connector_response_reference_id: response.order_id, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }) }, ..item.data diff --git a/crates/router/src/connector/opayo/transformers.rs b/crates/router/src/connector/opayo/transformers.rs index f55aa4325b06..992acfb5ef08 100644 --- a/crates/router/src/connector/opayo/transformers.rs +++ b/crates/router/src/connector/opayo/transformers.rs @@ -151,7 +151,7 @@ impl network_txn_id: None, connector_response_reference_id: Some(item.response.transaction_id), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) diff --git a/crates/router/src/connector/opennode/transformers.rs b/crates/router/src/connector/opennode/transformers.rs index 1e8239d377bb..265e6d649fce 100644 --- a/crates/router/src/connector/opennode/transformers.rs +++ b/crates/router/src/connector/opennode/transformers.rs @@ -144,7 +144,7 @@ impl network_txn_id: None, connector_response_reference_id: item.response.data.order_id, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }) } else { Ok(types::PaymentsResponseData::TransactionUnresolvedResponse { diff --git a/crates/router/src/connector/payme/transformers.rs b/crates/router/src/connector/payme/transformers.rs index 0e88ae236656..aedbb60547ec 100644 --- a/crates/router/src/connector/payme/transformers.rs +++ b/crates/router/src/connector/payme/transformers.rs @@ -259,7 +259,7 @@ impl TryFrom<&PaymePaySaleResponse> for types::PaymentsResponseData { network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }) } } @@ -326,7 +326,7 @@ impl From<&SaleQuery> for types::PaymentsResponseData { network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, } } } @@ -546,7 +546,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }), @@ -1124,7 +1124,7 @@ impl TryFrom> network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }) }; Ok(Self { diff --git a/crates/router/src/connector/paypal.rs b/crates/router/src/connector/paypal.rs index fb635708c23e..c7aef2ddb231 100644 --- a/crates/router/src/connector/paypal.rs +++ b/crates/router/src/connector/paypal.rs @@ -1227,7 +1227,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..data.clone() }) @@ -1278,7 +1278,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..data.clone() }) diff --git a/crates/router/src/connector/paypal/transformers.rs b/crates/router/src/connector/paypal/transformers.rs index 67204d9673c8..3a5d00079d9b 100644 --- a/crates/router/src/connector/paypal/transformers.rs +++ b/crates/router/src/connector/paypal/transformers.rs @@ -623,7 +623,7 @@ impl network_txn_id: None, connector_response_reference_id: Some(info_response.id.clone()), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -1859,7 +1859,7 @@ impl .clone() .or(Some(item.response.id)), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -1984,7 +1984,7 @@ impl purchase_units.map_or(item.response.id, |item| item.invoice_id.clone()), ), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -2039,7 +2039,7 @@ impl purchase_units.map_or(item.response.id, |item| item.invoice_id.clone()), ), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -2092,7 +2092,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -2130,7 +2130,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -2183,7 +2183,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -2252,7 +2252,7 @@ impl .clone() .or(Some(item.response.supplementary_data.related_ids.order_id)), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) @@ -2593,7 +2593,7 @@ impl TryFrom> .invoice_id .or(Some(item.response.id)), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), amount_captured: Some(amount_captured), ..item.data @@ -2645,7 +2645,7 @@ impl .invoice_id .or(Some(item.response.id)), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) diff --git a/crates/router/src/connector/plaid/transformers.rs b/crates/router/src/connector/plaid/transformers.rs index 29d4db1297f8..4e4fb1863ee7 100644 --- a/crates/router/src/connector/plaid/transformers.rs +++ b/crates/router/src/connector/plaid/transformers.rs @@ -314,7 +314,7 @@ impl network_txn_id: None, connector_response_reference_id: Some(item.response.payment_id), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }) }, ..item.data @@ -400,7 +400,7 @@ impl TryFrom item.response.id.clone(), )) } else { - let charge_id = item + let charges = item .response .latest_charge .as_ref() .map(|charge| match charge { - StripeChargeEnum::ChargeId(charge_id) => charge_id.clone(), + StripeChargeEnum::ChargeId(charges) => charges.clone(), StripeChargeEnum::ChargeObject(charge) => charge.id.clone(), }); Ok(types::PaymentsResponseData::TransactionResponse { @@ -2521,7 +2521,7 @@ impl network_txn_id, connector_response_reference_id: Some(item.response.id), incremental_authorization_allowed: None, - charge_id, + charges: None, //todoo }) }; @@ -2713,12 +2713,12 @@ impl }), _ => None, }; - let charge_id = item + let charges = item .response .latest_charge .as_ref() .map(|charge| match charge { - StripeChargeEnum::ChargeId(charge_id) => charge_id.clone(), + StripeChargeEnum::ChargeId(charges) => charges.clone(), StripeChargeEnum::ChargeObject(charge) => charge.id.clone(), }); Ok(types::PaymentsResponseData::TransactionResponse { @@ -2729,7 +2729,7 @@ impl network_txn_id: network_transaction_id, connector_response_reference_id: Some(item.response.id.clone()), incremental_authorization_allowed: None, - charge_id, + charges: None, //todoo }) }; @@ -2809,7 +2809,7 @@ impl network_txn_id: network_transaction_id, connector_response_reference_id: Some(item.response.id), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }) }; @@ -3520,7 +3520,7 @@ impl TryFrom .map(|cref| cref.code) .unwrap_or(Some(item.response.id)), incremental_authorization_allowed, - charge_id: None, + charges: None, }), ..item.data }) @@ -2177,7 +2177,7 @@ impl network_txn_id: None, connector_response_reference_id: Some(item.response.id), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }), diff --git a/crates/router/src/connector/wellsfargopayout/transformers.rs b/crates/router/src/connector/wellsfargopayout/transformers.rs index 135cb5f53cbf..3a194550dfd9 100644 --- a/crates/router/src/connector/wellsfargopayout/transformers.rs +++ b/crates/router/src/connector/wellsfargopayout/transformers.rs @@ -140,7 +140,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }) diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index 7a44b730c4fa..90c9b27e971a 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -6268,24 +6268,32 @@ pub fn validate_platform_request_for_marketplace( Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment( adyen_split_payment, )) => { - let total_split_amount = adyen_split_payment + let total_split_amount: i64 = adyen_split_payment .split_items .iter() - .map(|split_item| split_item.amount.unwrap_or(0).get_amount_as_i64()) + .map(|split_item| { + split_item + .amount + .unwrap_or(MinorUnit::new(0)) + .get_amount_as_i64() + }) .sum(); + match amount { api::Amount::Zero => { if total_split_amount != 0 { return Err(errors::ApiErrorResponse::InvalidDataValue { - field_name: "split_payments.adyen_split_payment.application_fees", + field_name: "split_payments.adyen_split_payment.amount", }); } } api::Amount::Value(amount) => { - if total_split_amount != amount.into() { + let i64_amount: i64 = amount.into(); + if !adyen_split_payment.split_items.is_empty() + && i64_amount != total_split_amount + { return Err(errors::ApiErrorResponse::PreconditionFailed { - message: "split_payments.adyen_split_payment.application_fees" - .to_string(), + message: "split_payments.adyen_split_payment.amount".to_string(), }); } } @@ -6293,62 +6301,58 @@ pub fn validate_platform_request_for_marketplace( adyen_split_payment .split_items .iter() - .try_for_each(|split_item| match split_item.split_type { - common_enums::AdyenSplitType::BalanceAccount => { - if split_item.account.is_none() { - return Err(errors::ApiErrorResponse::MissingRequiredField { - field_name: - "split_payments.adyen_split_payment.split_items.account", - }); - } - if split_item.reference.is_none() { - return Err(errors::ApiErrorResponse::MissingRequiredField { - field_name: - "split_payments.adyen_split_payment.split_items.reference", - }); - } - } - common_enums::AdyenSplitType::Commission => { - if split_item.amount.is_none() { - return Err(errors::ApiErrorResponse::MissingRequiredField { - field_name: "split_payments.adyen_split_payment.split_items.amount", - }); - } - } - enums::AdyenSplitType::Vat => { - if split_item.amount.is_none() { - return Err(errors::ApiErrorResponse::MissingRequiredField { - field_name: "split_payments.adyen_split_payment.split_items.amount", - }); - } - } - enums::AdyenSplitType::TopUp => { - if split_item.amount.is_none() { - return Err(errors::ApiErrorResponse::MissingRequiredField { - field_name: "split_payments.adyen_split_payment.split_items.amount", - }); - } - if split_item.account.is_none() { - return Err(errors::ApiErrorResponse::MissingRequiredField { - field_name: "split_payments.adyen_split_payment.split_items.amount", - }); + .try_for_each(|split_item| { + match split_item.split_type { + common_enums::AdyenSplitType::BalanceAccount => { + if split_item.account.is_none() { + return Err(errors::ApiErrorResponse::MissingRequiredField { + field_name: + "split_payments.adyen_split_payment.split_items.account", + }); + } + if split_item.reference.is_none() { + return Err(errors::ApiErrorResponse::MissingRequiredField { + field_name: + "split_payments.adyen_split_payment.split_items.reference", + }); + } } - if adyen_split_payment.store_id.is_some() { - return Err(errors::ApiErrorResponse::PreconditionFailed { - field_name: "Topup split is not available via Adyen plaform", - }); + common_enums::AdyenSplitType::Commission + | enums::AdyenSplitType::Vat + | enums::AdyenSplitType::TopUp => { + if split_item.amount.is_none() { + return Err(errors::ApiErrorResponse::MissingRequiredField { + field_name: + "split_payments.adyen_split_payment.split_items.amount", + }); + } + if let enums::AdyenSplitType::TopUp = split_item.split_type { + if split_item.account.is_none() { + return Err(errors::ApiErrorResponse::MissingRequiredField { + field_name: + "split_payments.adyen_split_payment.split_items.account", + }); + } + if adyen_split_payment.store_id.is_some() { + return Err(errors::ApiErrorResponse::PreconditionFailed { + message: "Topup split payment is not available via Adyen Platform" + .to_string(), + }); + } + } } - } - enums::AdyenSplitType::AcquiringFees - | enums::AdyenSplitType::PaymentFee - | enums::AdyenSplitType::AdyenFees - | enums::AdyenSplitType::AdyenCommission - | enums::AdyenSplitType::AdyenMarkup - | enums::AdyenSplitType::Interchange - | enums::AdyenSplitType::SchemeFee => (), - }) + enums::AdyenSplitType::AcquiringFees + | enums::AdyenSplitType::PaymentFee + | enums::AdyenSplitType::AdyenFees + | enums::AdyenSplitType::AdyenCommission + | enums::AdyenSplitType::AdyenMarkup + | enums::AdyenSplitType::Interchange + | enums::AdyenSplitType::SchemeFee => {} + }; + Ok(()) + })?; } - None => Ok(()), + None => (), } Ok(()) -} +} \ No newline at end of file diff --git a/crates/router/src/core/payments/operations/payment_response.rs b/crates/router/src/core/payments/operations/payment_response.rs index 988429a0eecb..b2156cc88e49 100644 --- a/crates/router/src/core/payments/operations/payment_response.rs +++ b/crates/router/src/core/payments/operations/payment_response.rs @@ -1531,7 +1531,7 @@ async fn payment_response_update_tracker( connector_metadata, connector_response_reference_id, incremental_authorization_allowed, - charge_id, + charges, .. } => { payment_data @@ -1728,7 +1728,7 @@ async fn payment_response_update_tracker( authentication_data, encoded_data, payment_method_data: additional_payment_method_data, - charge_id, + charge_id: None, //todoo connector_mandate_detail: payment_data .payment_attempt .connector_mandate_detail diff --git a/crates/router/src/core/payments/retry.rs b/crates/router/src/core/payments/retry.rs index 7ae536a1f193..c2f58fab82a2 100644 --- a/crates/router/src/core/payments/retry.rs +++ b/crates/router/src/core/payments/retry.rs @@ -420,7 +420,7 @@ where resource_id, connector_metadata, redirection_data, - charge_id, + charges, .. }) => { let encoded_data = payment_data.get_payment_attempt().encoded_data.clone(); @@ -465,7 +465,7 @@ where unified_code: None, unified_message: None, payment_method_data: additional_payment_method_data, - charge_id, + charge_id: None, //todooo connector_mandate_detail: None, }; diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index f94dc49ec9ef..7591801b18f9 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -906,7 +906,7 @@ where network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }); let additional_data = PaymentAdditionalData { @@ -2127,7 +2127,7 @@ where ) => Some( api_models::payments::SplitPaymentsResponse::StripeSplitPayment( api_models::payments::StripeSplitPaymentsResponse { - charge_id: payment_attempt.charge_id.clone(), + charge_id: None, //todoo payment_attempt.charges.clone(), charge_type: stripe_split_payment.charge_type, application_fees: stripe_split_payment.application_fees, transfer_account_id: stripe_split_payment.transfer_account_id, diff --git a/crates/router/src/core/refunds.rs b/crates/router/src/core/refunds.rs index 373a268d6918..eefacd44d840 100644 --- a/crates/router/src/core/refunds.rs +++ b/crates/router/src/core/refunds.rs @@ -474,7 +474,7 @@ pub async fn refund_retrieve_core( SplitRefundsRequest::try_from(SplitRefundInput { refund_request: split_refunds, payment_charges: split_payments, - charge_id: payment_attempt.charge_id.clone(), + charge_id: None, //todoo payment_attempt.charge_id.clone(), }) }) .transpose()?; From ddd1d63a04df5e92080682e7ded477a79bae7e72 Mon Sep 17 00:00:00 2001 From: "hyperswitch-bot[bot]" <148525504+hyperswitch-bot[bot]@users.noreply.github.com> Date: Mon, 13 Jan 2025 11:50:29 +0000 Subject: [PATCH 09/21] chore: run formatter --- crates/router/src/core/payments/helpers.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index 90c9b27e971a..19aba7e09e21 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -6355,4 +6355,4 @@ pub fn validate_platform_request_for_marketplace( None => (), } Ok(()) -} \ No newline at end of file +} From 69ada8a2fcdbad1aa9d8dd5928fe7be5dce6e6f8 Mon Sep 17 00:00:00 2001 From: AkshayaFoiger Date: Tue, 14 Jan 2025 21:12:05 +0530 Subject: [PATCH 10/21] refactor(router): add charges to payment attemot --- api-reference-v2/openapi_spec.json | 10 ++-- api-reference/openapi_spec.json | 10 ++-- crates/api_models/src/payments.rs | 38 +------------- crates/common_enums/Cargo.toml | 2 +- crates/common_types/src/payments.rs | 52 +++++++++++++++++++ crates/diesel_models/Cargo.toml | 2 +- crates/diesel_models/src/payment_attempt.rs | 28 ++++++++++ crates/diesel_models/src/schema.rs | 1 + .../src/payments/payment_attempt.rs | 6 +++ .../src/router_response_types.rs | 30 +---------- crates/openapi/src/openapi.rs | 6 +-- crates/openapi/src/openapi_v2.rs | 6 +-- .../payments/operations/payment_response.rs | 3 +- crates/router/src/core/payments/retry.rs | 3 +- .../router/src/core/payments/transformers.rs | 4 +- .../src/mock_db/payment_attempt.rs | 1 + .../src/payments/payment_attempt.rs | 3 ++ .../down.sql | 2 + .../up.sql | 3 ++ 19 files changed, 122 insertions(+), 88 deletions(-) create mode 100644 migrations/2025-01-14-832737_add_charges_to_payment_attempt/down.sql create mode 100644 migrations/2025-01-14-832737_add_charges_to_payment_attempt/up.sql diff --git a/api-reference-v2/openapi_spec.json b/api-reference-v2/openapi_spec.json index 636723d808a4..8425ca8e1963 100644 --- a/api-reference-v2/openapi_spec.json +++ b/api-reference-v2/openapi_spec.json @@ -15447,7 +15447,7 @@ "split_payments": { "allOf": [ { - "$ref": "#/components/schemas/SplitPaymentsResponse" + "$ref": "#/components/schemas/ConnectorChargeResponseData" } ], "nullable": true @@ -16347,7 +16347,7 @@ "split_payments": { "allOf": [ { - "$ref": "#/components/schemas/SplitPaymentsResponse" + "$ref": "#/components/schemas/ConnectorChargeResponseData" } ], "nullable": true @@ -20498,7 +20498,7 @@ ], "description": "Fee information for Split Payments to be charged on the payment being collected" }, - "SplitPaymentsResponse": { + "ConnectorChargeResponseData": { "oneOf": [ { "type": "object", @@ -20507,7 +20507,7 @@ ], "properties": { "stripe_split_payment": { - "$ref": "#/components/schemas/StripeSplitPaymentsResponse" + "$ref": "#/components/schemas/StripeChargeResponseData" } } } @@ -20631,7 +20631,7 @@ }, "additionalProperties": false }, - "StripeSplitPaymentsResponse": { + "StripeChargeResponseData": { "type": "object", "description": "Fee information to be charged on the payment being collected", "required": [ diff --git a/api-reference/openapi_spec.json b/api-reference/openapi_spec.json index 3c80fd8c4634..823797acfdc2 100644 --- a/api-reference/openapi_spec.json +++ b/api-reference/openapi_spec.json @@ -18805,7 +18805,7 @@ "split_payments": { "allOf": [ { - "$ref": "#/components/schemas/SplitPaymentsResponse" + "$ref": "#/components/schemas/ConnectorChargeResponseData" } ], "nullable": true @@ -20048,7 +20048,7 @@ "split_payments": { "allOf": [ { - "$ref": "#/components/schemas/SplitPaymentsResponse" + "$ref": "#/components/schemas/ConnectorChargeResponseData" } ], "nullable": true @@ -24934,7 +24934,7 @@ ], "description": "Fee information for Split Payments to be charged on the payment being collected" }, - "SplitPaymentsResponse": { + "ConnectorChargeResponseData": { "oneOf": [ { "type": "object", @@ -24943,7 +24943,7 @@ ], "properties": { "stripe_split_payment": { - "$ref": "#/components/schemas/StripeSplitPaymentsResponse" + "$ref": "#/components/schemas/StripeChargeResponseData" } } } @@ -25067,7 +25067,7 @@ }, "additionalProperties": false }, - "StripeSplitPaymentsResponse": { + "StripeChargeResponseData": { "type": "object", "description": "Fee information to be charged on the payment being collected", "required": [ diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index 89ead4167925..a1c37e0fcebd 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -4726,7 +4726,7 @@ pub struct PaymentsResponse { pub updated: Option, /// Fee information to be charged on the payment being collected - pub split_payments: Option, + pub split_payments: Option, /// You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. FRM Metadata is useful for storing additional, structured information on an object related to FRM. #[schema(value_type = Option, example = r#"{ "fulfillment_method" : "deliver", "coverage_request" : "fraud" }"#)] @@ -4991,42 +4991,6 @@ pub struct PaymentStartRedirectionParams { pub profile_id: id_type::ProfileId, } -/// Fee information to be charged on the payment being collected via Stripe -#[derive(Setter, Clone, Debug, PartialEq, serde::Serialize, ToSchema)] -pub struct StripeSplitPaymentsResponse { - /// Identifier for charge created for the payment - pub charge_id: Option, - - /// Type of charge (connector specific) - #[schema(value_type = PaymentChargeType, example = "direct")] - pub charge_type: api_enums::PaymentChargeType, - - /// Platform fees collected on the payment - #[schema(value_type = i64, example = 6540)] - pub application_fees: MinorUnit, - - /// Identifier for the reseller's account where the funds were transferred - pub transfer_account_id: String, -} - -#[derive(Setter, Clone, Debug, PartialEq, serde::Serialize, ToSchema)] -/// Fee information to be charged on the payment being collected via Adyen -pub struct AdyenSplitPaymentsResponse { - /// The store identifier - pub store_id: Option, - /// Data for the split items - pub split_items: Vec, -} - -#[derive(Clone, Debug, PartialEq, serde::Serialize, ToSchema)] -#[serde(rename_all = "snake_case")] -pub enum SplitPaymentsResponse { - /// StripeSplitPaymentsResponse - StripeSplitPayment(StripeSplitPaymentsResponse), - /// AdyenSplitPaymentsResponse - AdyenSplitPayment(AdyenSplitPaymentsResponse), -} - /// Details of external authentication #[derive(Setter, Clone, Default, Debug, PartialEq, serde::Serialize, ToSchema)] pub struct ExternalAuthenticationDetailsResponse { diff --git a/crates/common_enums/Cargo.toml b/crates/common_enums/Cargo.toml index 92fc2f02066b..f8f25593c8bd 100644 --- a/crates/common_enums/Cargo.toml +++ b/crates/common_enums/Cargo.toml @@ -13,7 +13,7 @@ openapi = [] payouts = [] [dependencies] -diesel = { version = "2.2.3", features = ["postgres"] } +diesel = { version = "2.2.3", features = ["postgres", "128-column-tables"]} serde = { version = "1.0.197", features = ["derive"] } serde_json = "1.0.115" strum = { version = "0.26", features = ["derive"] } diff --git a/crates/common_types/src/payments.rs b/crates/common_types/src/payments.rs index 83df36d7d9ab..c0a4cc4bd9cb 100644 --- a/crates/common_types/src/payments.rs +++ b/crates/common_types/src/payments.rs @@ -76,3 +76,55 @@ pub struct AdyenSplitItem { pub description: Option, } impl_to_sql_from_sql_json!(AdyenSplitItem); + +/// Fee information to be charged on the payment being collected via Stripe +#[derive( + Serialize, Deserialize, Debug, Clone, PartialEq, Eq, FromSqlRow, AsExpression, ToSchema, +)] +#[diesel(sql_type = Jsonb)] +#[serde(deny_unknown_fields)] +pub struct StripeChargeResponseData { + /// Identifier for charge created for the payment + pub charge_id: Option, + + /// Type of charge (connector specific) + #[schema(value_type = PaymentChargeType, example = "direct")] + pub charge_type: enums::PaymentChargeType, + + /// Platform fees collected on the payment + #[schema(value_type = i64, example = 6540)] + pub application_fees: MinorUnit, + + /// Identifier for the reseller's account where the funds were transferred + pub transfer_account_id: String, +} +impl_to_sql_from_sql_json!(StripeChargeResponseData); + +/// Fee information to be charged on the payment being collected via Adyen +#[derive( + Serialize, Deserialize, Debug, Clone, PartialEq, Eq, FromSqlRow, AsExpression, ToSchema, +)] +#[diesel(sql_type = Jsonb)] +#[serde(deny_unknown_fields)] +pub struct AdyenChargeResponseData { + /// The store identifier + pub store_id: Option, + /// Data for the split items + pub split_items: Vec, +} +impl_to_sql_from_sql_json!(AdyenChargeResponseData); + +/// Charge Information +#[derive( + Serialize, Deserialize, Debug, Clone, PartialEq, Eq, FromSqlRow, AsExpression, ToSchema, +)] +#[diesel(sql_type = Jsonb)] +#[serde(deny_unknown_fields)] +pub enum ConnectorChargeResponseData { + /// StripeChargeResponseData + StripeSplitPayment(StripeChargeResponseData), + /// AdyenChargeResponseData + AdyenSplitPayment(AdyenChargeResponseData), +} + +impl_to_sql_from_sql_json!(ConnectorChargeResponseData); diff --git a/crates/diesel_models/Cargo.toml b/crates/diesel_models/Cargo.toml index 5da67eb30759..4f02cc4aea87 100644 --- a/crates/diesel_models/Cargo.toml +++ b/crates/diesel_models/Cargo.toml @@ -17,7 +17,7 @@ payment_methods_v2 = [] [dependencies] async-bb8-diesel = { git = "https://github.com/jarnura/async-bb8-diesel", rev = "53b4ab901aab7635c8215fd1c2d542c8db443094" } -diesel = { version = "2.2.3", features = ["postgres", "serde_json", "time", "64-column-tables"] } +diesel = { version = "2.2.3", features = ["postgres", "serde_json", "time", "128-column-tables"] } error-stack = "0.4.1" rustc-hash = "1.1.0" serde = { version = "1.0.197", features = ["derive"] } diff --git a/crates/diesel_models/src/payment_attempt.rs b/crates/diesel_models/src/payment_attempt.rs index 03facc2ebab4..ec2b7c66ff42 100644 --- a/crates/diesel_models/src/payment_attempt.rs +++ b/crates/diesel_models/src/payment_attempt.rs @@ -94,6 +94,7 @@ pub struct PaymentAttempt { pub shipping_cost: Option, pub order_tax_amount: Option, pub connector_mandate_detail: Option, + pub charges: Option, } #[cfg(feature = "v1")] @@ -172,6 +173,7 @@ pub struct PaymentAttempt { pub order_tax_amount: Option, pub connector_transaction_data: Option, pub connector_mandate_detail: Option, + pub charges: Option, } #[cfg(feature = "v1")] @@ -471,6 +473,7 @@ pub enum PaymentAttemptUpdate { payment_method_data: Option, charge_id: Option, connector_mandate_detail: Option, + charges: Option, }, UnresolvedResponseUpdate { status: storage_enums::AttemptStatus, @@ -848,6 +851,7 @@ pub struct PaymentAttemptUpdateInternal { pub order_tax_amount: Option, pub connector_transaction_data: Option, pub connector_mandate_detail: Option, + pub charges: Option, } #[cfg(feature = "v1")] @@ -1031,6 +1035,7 @@ impl PaymentAttemptUpdate { order_tax_amount, connector_transaction_data, connector_mandate_detail, + charges, } = PaymentAttemptUpdateInternal::from(self).populate_derived_fields(&source); PaymentAttempt { amount: amount.unwrap_or(source.amount), @@ -1089,6 +1094,7 @@ impl PaymentAttemptUpdate { connector_transaction_data: connector_transaction_data .or(source.connector_transaction_data), connector_mandate_detail: connector_mandate_detail.or(source.connector_mandate_detail), + charges: charges.or(source.charges), ..source } } @@ -2141,6 +2147,7 @@ impl From for PaymentAttemptUpdateInternal { order_tax_amount: None, connector_transaction_data: None, connector_mandate_detail: None, + charges: None, }, PaymentAttemptUpdate::AuthenticationTypeUpdate { authentication_type, @@ -2197,6 +2204,7 @@ impl From for PaymentAttemptUpdateInternal { order_tax_amount: None, connector_transaction_data: None, connector_mandate_detail: None, + charges: None, }, PaymentAttemptUpdate::ConfirmUpdate { amount, @@ -2284,6 +2292,7 @@ impl From for PaymentAttemptUpdateInternal { order_tax_amount, connector_transaction_data: None, connector_mandate_detail, + charges: None, }, PaymentAttemptUpdate::VoidUpdate { status, @@ -2341,6 +2350,7 @@ impl From for PaymentAttemptUpdateInternal { order_tax_amount: None, connector_transaction_data: None, connector_mandate_detail: None, + charges: None, }, PaymentAttemptUpdate::RejectUpdate { status, @@ -2399,6 +2409,7 @@ impl From for PaymentAttemptUpdateInternal { order_tax_amount: None, connector_transaction_data: None, connector_mandate_detail: None, + charges: None, }, PaymentAttemptUpdate::BlocklistUpdate { status, @@ -2457,6 +2468,7 @@ impl From for PaymentAttemptUpdateInternal { order_tax_amount: None, connector_transaction_data: None, connector_mandate_detail: None, + charges: None, }, PaymentAttemptUpdate::ConnectorMandateDetailUpdate { connector_mandate_detail, @@ -2513,6 +2525,7 @@ impl From for PaymentAttemptUpdateInternal { order_tax_amount: None, connector_transaction_data: None, connector_mandate_detail, + charges: None, }, PaymentAttemptUpdate::PaymentMethodDetailsUpdate { payment_method_id, @@ -2569,6 +2582,7 @@ impl From for PaymentAttemptUpdateInternal { order_tax_amount: None, connector_transaction_data: None, connector_mandate_detail: None, + charges: None, }, PaymentAttemptUpdate::ResponseUpdate { status, @@ -2592,6 +2606,7 @@ impl From for PaymentAttemptUpdateInternal { payment_method_data, charge_id, connector_mandate_detail, + charges, } => { let (connector_transaction_id, connector_transaction_data) = connector_transaction_id @@ -2650,6 +2665,7 @@ impl From for PaymentAttemptUpdateInternal { shipping_cost: None, order_tax_amount: None, connector_mandate_detail, + charges, } } PaymentAttemptUpdate::ErrorUpdate { @@ -2723,6 +2739,7 @@ impl From for PaymentAttemptUpdateInternal { shipping_cost: None, order_tax_amount: None, connector_mandate_detail: None, + charges: None, } } PaymentAttemptUpdate::StatusUpdate { status, updated_by } => Self { @@ -2777,6 +2794,7 @@ impl From for PaymentAttemptUpdateInternal { order_tax_amount: None, connector_transaction_data: None, connector_mandate_detail: None, + charges: None, }, PaymentAttemptUpdate::UpdateTrackers { payment_token, @@ -2839,6 +2857,7 @@ impl From for PaymentAttemptUpdateInternal { order_tax_amount: None, connector_transaction_data: None, connector_mandate_detail: None, + charges: None, }, PaymentAttemptUpdate::UnresolvedResponseUpdate { status, @@ -2908,6 +2927,7 @@ impl From for PaymentAttemptUpdateInternal { shipping_cost: None, order_tax_amount: None, connector_mandate_detail: None, + charges: None, } } PaymentAttemptUpdate::PreprocessingUpdate { @@ -2976,6 +2996,7 @@ impl From for PaymentAttemptUpdateInternal { shipping_cost: None, order_tax_amount: None, connector_mandate_detail: None, + charges: None, } } PaymentAttemptUpdate::CaptureUpdate { @@ -3034,6 +3055,7 @@ impl From for PaymentAttemptUpdateInternal { order_tax_amount: None, connector_transaction_data: None, connector_mandate_detail: None, + charges: None, }, PaymentAttemptUpdate::AmountToCaptureUpdate { status, @@ -3091,6 +3113,7 @@ impl From for PaymentAttemptUpdateInternal { order_tax_amount: None, connector_transaction_data: None, connector_mandate_detail: None, + charges: None, }, PaymentAttemptUpdate::ConnectorResponse { authentication_data, @@ -3157,6 +3180,7 @@ impl From for PaymentAttemptUpdateInternal { shipping_cost: None, order_tax_amount: None, connector_mandate_detail: None, + charges: None, } } PaymentAttemptUpdate::IncrementalAuthorizationAmountUpdate { @@ -3214,6 +3238,7 @@ impl From for PaymentAttemptUpdateInternal { order_tax_amount: None, connector_transaction_data: None, connector_mandate_detail: None, + charges: None, }, PaymentAttemptUpdate::AuthenticationUpdate { status, @@ -3273,6 +3298,7 @@ impl From for PaymentAttemptUpdateInternal { order_tax_amount: None, connector_transaction_data: None, connector_mandate_detail: None, + charges: None, }, PaymentAttemptUpdate::ManualUpdate { status, @@ -3341,6 +3367,7 @@ impl From for PaymentAttemptUpdateInternal { shipping_cost: None, order_tax_amount: None, connector_mandate_detail: None, + charges: None, } } PaymentAttemptUpdate::PostSessionTokensUpdate { @@ -3398,6 +3425,7 @@ impl From for PaymentAttemptUpdateInternal { order_tax_amount: None, connector_transaction_data: None, connector_mandate_detail: None, + charges: None, }, } } diff --git a/crates/diesel_models/src/schema.rs b/crates/diesel_models/src/schema.rs index 95bb714cb711..d546008ad457 100644 --- a/crates/diesel_models/src/schema.rs +++ b/crates/diesel_models/src/schema.rs @@ -889,6 +889,7 @@ diesel::table! { #[max_length = 512] connector_transaction_data -> Nullable, connector_mandate_detail -> Nullable, + charges -> Nullable, } } diff --git a/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs b/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs index 0a7ada39ecdb..b6a56eec0676 100644 --- a/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs +++ b/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs @@ -590,6 +590,7 @@ pub struct PaymentAttempt { pub profile_id: id_type::ProfileId, pub organization_id: id_type::OrganizationId, pub connector_mandate_detail: Option, + pub charges: Option, } #[cfg(feature = "v1")] @@ -950,6 +951,7 @@ pub enum PaymentAttemptUpdate { payment_method_data: Option, charge_id: Option, connector_mandate_detail: Option, + charges: Option, }, UnresolvedResponseUpdate { status: storage_enums::AttemptStatus, @@ -1220,6 +1222,7 @@ impl PaymentAttemptUpdate { payment_method_data, charge_id, connector_mandate_detail, + charges, } => DieselPaymentAttemptUpdate::ResponseUpdate { status, connector, @@ -1242,6 +1245,7 @@ impl PaymentAttemptUpdate { payment_method_data, charge_id, connector_mandate_detail, + charges, }, Self::UnresolvedResponseUpdate { status, @@ -1551,6 +1555,7 @@ impl behaviour::Conversion for PaymentAttempt { order_tax_amount: self.net_amount.get_order_tax_amount(), shipping_cost: self.net_amount.get_shipping_cost(), connector_mandate_detail: self.connector_mandate_detail, + charges: self.charges, }) } @@ -1632,6 +1637,7 @@ impl behaviour::Conversion for PaymentAttempt { profile_id: storage_model.profile_id, organization_id: storage_model.organization_id, connector_mandate_detail: storage_model.connector_mandate_detail, + charges: storage_model.charges, }) } .await diff --git a/crates/hyperswitch_domain_models/src/router_response_types.rs b/crates/hyperswitch_domain_models/src/router_response_types.rs index 1c6e6ef56d91..3765756dbea2 100644 --- a/crates/hyperswitch_domain_models/src/router_response_types.rs +++ b/crates/hyperswitch_domain_models/src/router_response_types.rs @@ -26,7 +26,7 @@ pub enum PaymentsResponseData { network_txn_id: Option, connector_response_reference_id: Option, incremental_authorization_allowed: Option, - charges: Option>, + charges: Option<::common_types::payments::ConnectorChargeResponseData>, }, MultipleCaptureResponse { // pending_capture_id_list: Vec, @@ -506,34 +506,6 @@ pub enum AuthenticationResponseData { }, } -#[derive(Debug, Clone)] -pub struct StripeChargeResponseData { - pub application_fee: MinorUnit, - pub charge_type: common_enums::StripeChargeType, - pub charge_id: Option, - pub transfer_account_id: Option, -} - -#[derive(Debug, Clone)] -pub struct AdyenChargeResponseData { - pub store_id: Option, - pub split_items: Vec, -} - -#[derive(Debug, Clone)] -pub struct AdyenSplitItemResponse { - pub amount: MinorUnit, - pub split_type: common_enums::AdyenSplitType, - pub refernce: Option, - pub account: Option, -} - -#[derive(Debug, Clone)] -pub enum ConnectorChargeResponseData { - Stripe(StripeChargeResponseData), - Adyen(AdyenChargeResponseData), -} - #[derive(Debug, Clone)] pub struct CompleteAuthorizeRedirectResponse { pub params: Option>, diff --git a/crates/openapi/src/openapi.rs b/crates/openapi/src/openapi.rs index 0abb7fffbab6..00292a702e15 100644 --- a/crates/openapi/src/openapi.rs +++ b/crates/openapi/src/openapi.rs @@ -221,9 +221,9 @@ Never share your secret api keys. Keep them guarded and secure. common_utils::types::ChargeRefunds, common_types::refunds::SplitRefund, common_types::refunds::StripeSplitRefundRequest, - api_models::payments::SplitPaymentsResponse, - api_models::payments::StripeSplitPaymentsResponse, - api_models::payments::AdyenSplitPaymentsResponse, + api_models::payments::ConnectorChargeResponseData, + api_models::payments::StripeChargeResponseData, + api_models::payments::AdyenChargeResponseData, api_models::refunds::RefundRequest, api_models::refunds::RefundType, api_models::refunds::RefundResponse, diff --git a/crates/openapi/src/openapi_v2.rs b/crates/openapi/src/openapi_v2.rs index 8189504350db..e357be26649d 100644 --- a/crates/openapi/src/openapi_v2.rs +++ b/crates/openapi/src/openapi_v2.rs @@ -165,9 +165,9 @@ Never share your secret api keys. Keep them guarded and secure. common_utils::types::ChargeRefunds, common_types::payment_methods::PaymentMethodsEnabled, common_types::refunds::SplitRefund, - api_models::payments::SplitPaymentsResponse, - api_models::payments::StripeSplitPaymentsResponse, - api_models::payments::AdyenSplitPaymentsResponse, + api_models::payments::ConnectorChargeResponseData, + api_models::payments::StripeChargeResponseData, + api_models::payments::AdyenChargeResponseData, api_models::refunds::RefundRequest, api_models::refunds::RefundsCreateRequest, api_models::refunds::RefundErrorDetails, diff --git a/crates/router/src/core/payments/operations/payment_response.rs b/crates/router/src/core/payments/operations/payment_response.rs index b2156cc88e49..0736267cc501 100644 --- a/crates/router/src/core/payments/operations/payment_response.rs +++ b/crates/router/src/core/payments/operations/payment_response.rs @@ -1728,11 +1728,12 @@ async fn payment_response_update_tracker( authentication_data, encoded_data, payment_method_data: additional_payment_method_data, - charge_id: None, //todoo + charge_id: None, //depreciated connector_mandate_detail: payment_data .payment_attempt .connector_mandate_detail .clone(), + charges, }), ), }; diff --git a/crates/router/src/core/payments/retry.rs b/crates/router/src/core/payments/retry.rs index c2f58fab82a2..f50f0fe3a9d5 100644 --- a/crates/router/src/core/payments/retry.rs +++ b/crates/router/src/core/payments/retry.rs @@ -465,8 +465,9 @@ where unified_code: None, unified_message: None, payment_method_data: additional_payment_method_data, - charge_id: None, //todooo + charge_id: None, connector_mandate_detail: None, + charges, }; #[cfg(feature = "v1")] diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index 7591801b18f9..d913f1c819cc 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -2125,8 +2125,8 @@ where common_types::payments::SplitPaymentsRequest::StripeSplitPayment( stripe_split_payment, ) => Some( - api_models::payments::SplitPaymentsResponse::StripeSplitPayment( - api_models::payments::StripeSplitPaymentsResponse { + common_types::payments::ConnectorChargeResponseData::StripeSplitPayment( + common_types::payments::StripeChargeResponseData { charge_id: None, //todoo payment_attempt.charges.clone(), charge_type: stripe_split_payment.charge_type, application_fees: stripe_split_payment.application_fees, diff --git a/crates/storage_impl/src/mock_db/payment_attempt.rs b/crates/storage_impl/src/mock_db/payment_attempt.rs index 0415625f7ebb..b4f7eee42949 100644 --- a/crates/storage_impl/src/mock_db/payment_attempt.rs +++ b/crates/storage_impl/src/mock_db/payment_attempt.rs @@ -195,6 +195,7 @@ impl PaymentAttemptInterface for MockDb { organization_id: payment_attempt.organization_id, profile_id: payment_attempt.profile_id, connector_mandate_detail: payment_attempt.connector_mandate_detail, + charges: None, }; payment_attempts.push(payment_attempt.clone()); Ok(payment_attempt) diff --git a/crates/storage_impl/src/payments/payment_attempt.rs b/crates/storage_impl/src/payments/payment_attempt.rs index 06c7fefe85fa..e41e7125ba0a 100644 --- a/crates/storage_impl/src/payments/payment_attempt.rs +++ b/crates/storage_impl/src/payments/payment_attempt.rs @@ -564,6 +564,7 @@ impl PaymentAttemptInterface for KVRouterStore { organization_id: payment_attempt.organization_id.clone(), profile_id: payment_attempt.profile_id.clone(), connector_mandate_detail: payment_attempt.connector_mandate_detail.clone(), + charges: None, }; let field = format!("pa_{}", created_attempt.attempt_id); @@ -1511,6 +1512,7 @@ impl DataModelExt for PaymentAttempt { shipping_cost: self.net_amount.get_shipping_cost(), order_tax_amount: self.net_amount.get_order_tax_amount(), connector_mandate_detail: self.connector_mandate_detail, + charges: self.charges, } } @@ -1587,6 +1589,7 @@ impl DataModelExt for PaymentAttempt { organization_id: storage_model.organization_id, profile_id: storage_model.profile_id, connector_mandate_detail: storage_model.connector_mandate_detail, + charges: storage_model.charges, } } } diff --git a/migrations/2025-01-14-832737_add_charges_to_payment_attempt/down.sql b/migrations/2025-01-14-832737_add_charges_to_payment_attempt/down.sql new file mode 100644 index 000000000000..cdd8328c8ee5 --- /dev/null +++ b/migrations/2025-01-14-832737_add_charges_to_payment_attempt/down.sql @@ -0,0 +1,2 @@ +ALTER TABLE payment_attempt +DROP COLUMN charges; \ No newline at end of file diff --git a/migrations/2025-01-14-832737_add_charges_to_payment_attempt/up.sql b/migrations/2025-01-14-832737_add_charges_to_payment_attempt/up.sql new file mode 100644 index 000000000000..10fa978f9dc6 --- /dev/null +++ b/migrations/2025-01-14-832737_add_charges_to_payment_attempt/up.sql @@ -0,0 +1,3 @@ +ALTER TABLE payment_attempt +ADD COLUMN charges JSONB +DEFAULT NULL; \ No newline at end of file From c72e35c241689d46fbc611261ba776bd704bef5c Mon Sep 17 00:00:00 2001 From: AkshayaFoiger Date: Tue, 14 Jan 2025 23:40:21 +0530 Subject: [PATCH 11/21] refactor(router): fix stripe --- crates/router/src/connector/stripe.rs | 23 +++------- .../src/connector/stripe/transformers.rs | 43 ++++++++++++++++--- crates/router/src/connector/utils.rs | 28 ++++++++++++ crates/router/src/core/payments/helpers.rs | 2 +- .../router/src/core/payments/transformers.rs | 22 +--------- crates/router/src/core/refunds.rs | 6 +-- .../router/src/core/refunds/transformers.rs | 6 +-- crates/router/tests/connectors/utils.rs | 2 +- 8 files changed, 80 insertions(+), 52 deletions(-) diff --git a/crates/router/src/connector/stripe.rs b/crates/router/src/connector/stripe.rs index a96e90919aff..2771666d8089 100644 --- a/crates/router/src/connector/stripe.rs +++ b/crates/router/src/connector/stripe.rs @@ -766,19 +766,15 @@ impl let mut api_key = self.get_auth_header(&req.connector_auth_type)?; header.append(&mut api_key); - if let Some(split_payments) = &req.request.split_payments { - match split_payments { - common_types::payments::SplitPaymentsRequest::StripeSplitPayment( - stripe_split_payment, - ) => { + if let Some(common_types::payments::SplitPaymentsRequest::StripeSplitPayment( + stripe_split_payment, + )) = &req.request.split_payments { + transformers::transform_headers_for_connect_platform( stripe_split_payment.charge_type.clone(), stripe_split_payment.transfer_account_id.clone(), &mut header, ); - } - common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(_) => todo!(), //todooo - } } Ok(header) } @@ -944,11 +940,9 @@ impl let mut api_key = self.get_auth_header(&req.connector_auth_type)?; header.append(&mut api_key); - if let Some(split_payments) = &req.request.split_payments { - match split_payments { - common_types::payments::SplitPaymentsRequest::StripeSplitPayment( - stripe_split_payment, - ) => { + if let Some(common_types::payments::SplitPaymentsRequest::StripeSplitPayment( + stripe_split_payment, + )) = &req.request.split_payments { if stripe_split_payment.charge_type == api::enums::PaymentChargeType::Stripe( api::enums::StripeChargeType::Direct, @@ -963,9 +957,6 @@ impl )]; header.append(&mut customer_account_header); } - } - common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(_) => todo!(), //todooo - } } Ok(header) } diff --git a/crates/router/src/connector/stripe/transformers.rs b/crates/router/src/connector/stripe/transformers.rs index ddeb4ae725f3..eb123194f268 100644 --- a/crates/router/src/connector/stripe/transformers.rs +++ b/crates/router/src/connector/stripe/transformers.rs @@ -1953,8 +1953,8 @@ impl TryFrom<(&types::PaymentsAuthorizeRouterData, MinorUnit)> for PaymentIntent }; (charges, None) } - Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(_)) => todo!(), //todooo - None => (None, item.connector_customer.to_owned().map(Secret::new)), + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(_)) + | None => (None, item.connector_customer.to_owned().map(Secret::new)), }; Ok(Self { @@ -2452,6 +2452,8 @@ fn extract_payment_method_connector_response_from_latest_attempt( impl TryFrom> for types::RouterData + where + T: connector_util::SplitPaymentData, { type Error = error_stack::Report; fn try_from( @@ -2512,7 +2514,9 @@ impl .map(|charge| match charge { StripeChargeEnum::ChargeId(charges) => charges.clone(), StripeChargeEnum::ChargeObject(charge) => charge.id.clone(), - }); + }) + .and_then(|charge_id| construct_charge_response(charge_id, &item.data.request)); + Ok(types::PaymentsResponseData::TransactionResponse { resource_id: types::ResponseId::ConnectorTransactionId(item.response.id.clone()), redirection_data: Box::new(redirection_data), @@ -2521,7 +2525,7 @@ impl network_txn_id, connector_response_reference_id: Some(item.response.id), incremental_authorization_allowed: None, - charges: None, //todoo + charges, }) }; @@ -2610,6 +2614,8 @@ pub fn get_connector_metadata( impl TryFrom> for types::RouterData + where + T: connector_util::SplitPaymentData, { type Error = error_stack::Report; fn try_from( @@ -2720,7 +2726,9 @@ impl .map(|charge| match charge { StripeChargeEnum::ChargeId(charges) => charges.clone(), StripeChargeEnum::ChargeObject(charge) => charge.id.clone(), - }); + }) + .and_then(|charge_id| construct_charge_response(charge_id, &item.data.request)); + Ok(types::PaymentsResponseData::TransactionResponse { resource_id: types::ResponseId::ConnectorTransactionId(item.response.id.clone()), redirection_data: Box::new(redirection_data), @@ -2729,7 +2737,7 @@ impl network_txn_id: network_transaction_id, connector_response_reference_id: Some(item.response.id.clone()), incremental_authorization_allowed: None, - charges: None, //todoo + charges, }) }; @@ -3520,7 +3528,7 @@ impl TryFrom( + charge_id: String, + request: &T, +) -> Option +where + T: connector_util::SplitPaymentData, + { + let charge_request = request.get_split_payment_data(); + if let Some(common_types::payments::SplitPaymentsRequest::StripeSplitPayment(stripe_split_payment)) = charge_request { + let stripe_charge_response = common_types::payments::StripeChargeResponseData{ + charge_id: Some(charge_id), + charge_type: stripe_split_payment.charge_type, + application_fees: stripe_split_payment.application_fees, + transfer_account_id: stripe_split_payment.transfer_account_id, + }; + Some(common_types::payments::ConnectorChargeResponseData::StripeSplitPayment(stripe_charge_response)) +} else { + None +} +} \ No newline at end of file diff --git a/crates/router/src/connector/utils.rs b/crates/router/src/connector/utils.rs index 171f19bc70ab..32d60fc5b5f6 100644 --- a/crates/router/src/connector/utils.rs +++ b/crates/router/src/connector/utils.rs @@ -759,6 +759,34 @@ impl PaymentsCaptureRequestData for types::PaymentsCaptureData { } } +pub trait SplitPaymentData { + fn get_split_payment_data(&self) -> Option; +} + +impl SplitPaymentData for types::PaymentsCaptureData { + fn get_split_payment_data(&self) -> Option { + None + } +} + +impl SplitPaymentData for types::PaymentsAuthorizeData { + fn get_split_payment_data(&self) -> Option { + self.split_payments.clone() + } +} + +impl SplitPaymentData for types::PaymentsSyncData { + fn get_split_payment_data(&self) -> Option { + self.split_payments.clone() + } +} + +impl SplitPaymentData for PaymentsCancelData { + fn get_split_payment_data(&self) -> Option { + None + } +} + pub trait RevokeMandateRequestData { fn get_connector_mandate_id(&self) -> Result; } diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index 19aba7e09e21..90c9b27e971a 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -6355,4 +6355,4 @@ pub fn validate_platform_request_for_marketplace( None => (), } Ok(()) -} +} \ No newline at end of file diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index d913f1c819cc..e889365020cd 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -2119,26 +2119,6 @@ where ) }); - let split_payments_response = match payment_intent.split_payments { - None => None, - Some(split_payments) => match split_payments { - common_types::payments::SplitPaymentsRequest::StripeSplitPayment( - stripe_split_payment, - ) => Some( - common_types::payments::ConnectorChargeResponseData::StripeSplitPayment( - common_types::payments::StripeChargeResponseData { - charge_id: None, //todoo payment_attempt.charges.clone(), - charge_type: stripe_split_payment.charge_type, - application_fees: stripe_split_payment.application_fees, - transfer_account_id: stripe_split_payment.transfer_account_id, - }, - ), - ), - common_types::payments::SplitPaymentsRequest::AdyenSplitPayment( - adyen_split_payment, - ) => todo!(), //todoooo - }, - }; let mandate_data = payment_data.get_setup_mandate().map(|d| api::MandateData { customer_acceptance: d @@ -2318,7 +2298,7 @@ where .get_payment_method_info() .map(|info| info.status), updated: Some(payment_intent.modified_at), - split_payments: split_payments_response, + split_payments: payment_attempt.charges, frm_metadata: payment_intent.frm_metadata, merchant_order_reference_id: payment_intent.merchant_order_reference_id, order_tax_amount, diff --git a/crates/router/src/core/refunds.rs b/crates/router/src/core/refunds.rs index eefacd44d840..91cc0e4e0ed6 100644 --- a/crates/router/src/core/refunds.rs +++ b/crates/router/src/core/refunds.rs @@ -466,15 +466,15 @@ pub async fn refund_retrieve_core( .await .transpose()?; - let split_refunds_req: Option = payment_intent - .split_payments + let split_refunds_req: Option = payment_attempt + .charges .clone() .zip(refund.split_refunds.clone()) .map(|(split_payments, split_refunds)| { SplitRefundsRequest::try_from(SplitRefundInput { refund_request: split_refunds, payment_charges: split_payments, - charge_id: None, //todoo payment_attempt.charge_id.clone(), + charge_id: payment_attempt.charge_id.clone(), }) }) .transpose()?; diff --git a/crates/router/src/core/refunds/transformers.rs b/crates/router/src/core/refunds/transformers.rs index 9833920690f7..3d4b8702901d 100644 --- a/crates/router/src/core/refunds/transformers.rs +++ b/crates/router/src/core/refunds/transformers.rs @@ -6,7 +6,7 @@ use crate::core::errors; pub struct SplitRefundInput { pub refund_request: common_types::refunds::SplitRefund, - pub payment_charges: common_types::payments::SplitPaymentsRequest, + pub payment_charges: common_types::payments::ConnectorChargeResponseData, pub charge_id: Option, } @@ -23,10 +23,10 @@ impl TryFrom for router_request_types::SplitRefundsRequest { match refund_request { common_types::refunds::SplitRefund::StripeSplitRefund(stripe_refund) => { match payment_charges { - common_types::payments::SplitPaymentsRequest::StripeSplitPayment( + common_types::payments::ConnectorChargeResponseData::StripeSplitPayment( stripe_payment, ) => { - let charge_id = charge_id.ok_or_else(|| { + let charge_id = stripe_payment.charge_id.or(charge_id).ok_or_else(|| { report!(errors::ApiErrorResponse::InternalServerError) .attach_printable("Missing `charge_id` in PaymentAttempt.") })?; diff --git a/crates/router/tests/connectors/utils.rs b/crates/router/tests/connectors/utils.rs index 361cda63a9f9..2dee0f0b1a29 100644 --- a/crates/router/tests/connectors/utils.rs +++ b/crates/router/tests/connectors/utils.rs @@ -1126,7 +1126,7 @@ pub fn get_connector_metadata( network_txn_id: _, connector_response_reference_id: _, incremental_authorization_allowed: _, - charge_id: _, + charges: _, }) => connector_metadata, _ => None, } From d052ddde50cd3a9389ca322f1acd7838fce47322 Mon Sep 17 00:00:00 2001 From: AkshayaFoiger Date: Fri, 17 Jan 2025 10:13:11 +0530 Subject: [PATCH 12/21] refactor(router): fix validation --- crates/common_types/src/domain.rs | 43 +++++++++ crates/common_types/src/lib.rs | 1 + crates/common_types/src/payments.rs | 55 +---------- crates/common_types/src/refunds.rs | 3 + .../src/router_response_types.rs | 6 +- crates/openapi/src/openapi.rs | 2 +- crates/openapi/src/openapi_v2.rs | 2 +- crates/router/src/core/refunds.rs | 94 ++++++++++++++----- .../router/src/core/refunds/transformers.rs | 17 +++- crates/router/src/core/refunds/validator.rs | 23 +++-- 10 files changed, 155 insertions(+), 91 deletions(-) create mode 100644 crates/common_types/src/domain.rs diff --git a/crates/common_types/src/domain.rs b/crates/common_types/src/domain.rs new file mode 100644 index 000000000000..0303626f5346 --- /dev/null +++ b/crates/common_types/src/domain.rs @@ -0,0 +1,43 @@ +//! Common types + +use common_enums::enums; +use common_utils::{impl_to_sql_from_sql_json, types::MinorUnit}; +use diesel::{sql_types::Jsonb, AsExpression, FromSqlRow}; +use serde::{Deserialize, Serialize}; +use utoipa::ToSchema; + +#[derive( + Serialize, Deserialize, Debug, Clone, PartialEq, Eq, FromSqlRow, AsExpression, ToSchema, +)] +#[diesel(sql_type = Jsonb)] +#[serde(deny_unknown_fields)] +/// Fee information for Split Payments to be charged on the payment being collected for Adyen +pub struct AdyenSplitData { + /// The store identifier + pub store_id: Option, + /// Data for the split items + pub split_items: Vec, +} +impl_to_sql_from_sql_json!(AdyenSplitData); + +#[derive( + Serialize, Deserialize, Debug, Clone, PartialEq, Eq, FromSqlRow, AsExpression, ToSchema, +)] +#[diesel(sql_type = Jsonb)] +#[serde(deny_unknown_fields)] +/// Data for the split items +pub struct AdyenSplitItem { + /// The amount of the split item + #[schema(value_type = i64, example = 6540)] + pub amount: Option, + /// Defines type of split item + #[schema(value_type = AdyenSplitType, example = "balance_account")] + pub split_type: enums::AdyenSplitType, + /// The unique identifier of the account to which the split amount is allocated. + pub account: Option, + /// Unique Identifier for the split item + pub reference: Option, + /// Description for the part of the payment that will be allocated to the specified account. + pub description: Option, +} +impl_to_sql_from_sql_json!(AdyenSplitItem); diff --git a/crates/common_types/src/lib.rs b/crates/common_types/src/lib.rs index b0b258ecb6d8..810d4a7e7006 100644 --- a/crates/common_types/src/lib.rs +++ b/crates/common_types/src/lib.rs @@ -5,3 +5,4 @@ pub mod payment_methods; pub mod payments; pub mod refunds; +pub mod domain; diff --git a/crates/common_types/src/payments.rs b/crates/common_types/src/payments.rs index c0a4cc4bd9cb..98f922beefd9 100644 --- a/crates/common_types/src/payments.rs +++ b/crates/common_types/src/payments.rs @@ -1,5 +1,6 @@ //! Payment related types +use crate::domain as domain_types; use common_enums::enums; use common_utils::{impl_to_sql_from_sql_json, types::MinorUnit}; use diesel::{sql_types::Jsonb, AsExpression, FromSqlRow}; @@ -17,7 +18,7 @@ pub enum SplitPaymentsRequest { /// StripeSplitPayment StripeSplitPayment(StripeSplitPaymentRequest), /// AdyenSplitPayment - AdyenSplitPayment(AdyenSplitPaymentsRequest), + AdyenSplitPayment(domain_types::AdyenSplitData), } impl_to_sql_from_sql_json!(SplitPaymentsRequest); @@ -41,42 +42,6 @@ pub struct StripeSplitPaymentRequest { } impl_to_sql_from_sql_json!(StripeSplitPaymentRequest); -#[derive( - Serialize, Deserialize, Debug, Clone, PartialEq, Eq, FromSqlRow, AsExpression, ToSchema, -)] -#[diesel(sql_type = Jsonb)] -#[serde(deny_unknown_fields)] -/// Fee information for Split Payments to be charged on the payment being collected for Adyen -pub struct AdyenSplitPaymentsRequest { - /// The store identifier - pub store_id: Option, - /// Data for the split items - pub split_items: Vec, -} -impl_to_sql_from_sql_json!(AdyenSplitPaymentsRequest); - -#[derive( - Serialize, Deserialize, Debug, Clone, PartialEq, Eq, FromSqlRow, AsExpression, ToSchema, -)] -#[diesel(sql_type = Jsonb)] -#[serde(deny_unknown_fields)] -/// Data for the split items -pub struct AdyenSplitItem { - /// The amount of the split item - #[schema(value_type = i64, example = 6540)] - pub amount: Option, - /// Defines type of split item - #[schema(value_type = AdyenSplitType, example = "balance_account")] - pub split_type: enums::AdyenSplitType, - /// The unique identifier of the account to which the split amount is allocated. - pub account: Option, - /// Unique Identifier for the split item - pub reference: Option, - /// Description for the part of the payment that will be allocated to the specified account. - pub description: Option, -} -impl_to_sql_from_sql_json!(AdyenSplitItem); - /// Fee information to be charged on the payment being collected via Stripe #[derive( Serialize, Deserialize, Debug, Clone, PartialEq, Eq, FromSqlRow, AsExpression, ToSchema, @@ -100,19 +65,7 @@ pub struct StripeChargeResponseData { } impl_to_sql_from_sql_json!(StripeChargeResponseData); -/// Fee information to be charged on the payment being collected via Adyen -#[derive( - Serialize, Deserialize, Debug, Clone, PartialEq, Eq, FromSqlRow, AsExpression, ToSchema, -)] -#[diesel(sql_type = Jsonb)] -#[serde(deny_unknown_fields)] -pub struct AdyenChargeResponseData { - /// The store identifier - pub store_id: Option, - /// Data for the split items - pub split_items: Vec, -} -impl_to_sql_from_sql_json!(AdyenChargeResponseData); + /// Charge Information #[derive( @@ -124,7 +77,7 @@ pub enum ConnectorChargeResponseData { /// StripeChargeResponseData StripeSplitPayment(StripeChargeResponseData), /// AdyenChargeResponseData - AdyenSplitPayment(AdyenChargeResponseData), + AdyenSplitPayment(domain_types::AdyenSplitData), } impl_to_sql_from_sql_json!(ConnectorChargeResponseData); diff --git a/crates/common_types/src/refunds.rs b/crates/common_types/src/refunds.rs index e4b7c5a336fa..d25fad10bee8 100644 --- a/crates/common_types/src/refunds.rs +++ b/crates/common_types/src/refunds.rs @@ -4,6 +4,7 @@ use common_utils::impl_to_sql_from_sql_json; use diesel::{sql_types::Jsonb, AsExpression, FromSqlRow}; use serde::{Deserialize, Serialize}; use utoipa::ToSchema; +use crate::domain as domain_types; #[derive( Serialize, Deserialize, Debug, Clone, PartialEq, Eq, FromSqlRow, AsExpression, ToSchema, @@ -15,6 +16,8 @@ use utoipa::ToSchema; pub enum SplitRefund { /// StripeSplitRefundRequest StripeSplitRefund(StripeSplitRefundRequest), + /// AdyenSplitRefundRequest + AdyenSplitRefund(domain_types::AdyenSplitData), } impl_to_sql_from_sql_json!(SplitRefund); diff --git a/crates/hyperswitch_domain_models/src/router_response_types.rs b/crates/hyperswitch_domain_models/src/router_response_types.rs index 3765756dbea2..399ab446c4f2 100644 --- a/crates/hyperswitch_domain_models/src/router_response_types.rs +++ b/crates/hyperswitch_domain_models/src/router_response_types.rs @@ -2,7 +2,7 @@ pub mod disputes; pub mod fraud_check; use std::collections::HashMap; -use common_utils::{request::Method, types as common_types, types::MinorUnit}; +use common_utils::{request::Method, types::MinorUnit}; pub use disputes::{AcceptDisputeResponse, DefendDisputeResponse, SubmitEvidenceResponse}; use crate::{ @@ -26,7 +26,7 @@ pub enum PaymentsResponseData { network_txn_id: Option, connector_response_reference_id: Option, incremental_authorization_allowed: Option, - charges: Option<::common_types::payments::ConnectorChargeResponseData>, + charges: Option, }, MultipleCaptureResponse { // pending_capture_id_list: Vec, @@ -474,7 +474,7 @@ pub struct MandateRevokeResponseData { #[derive(Debug, Clone)] pub enum AuthenticationResponseData { PreAuthVersionCallResponse { - maximum_supported_3ds_version: common_types::SemanticVersion, + maximum_supported_3ds_version: common_utils::types::SemanticVersion, }, PreAuthThreeDsMethodCallResponse { threeds_server_transaction_id: String, diff --git a/crates/openapi/src/openapi.rs b/crates/openapi/src/openapi.rs index 00292a702e15..15ecf4ae6909 100644 --- a/crates/openapi/src/openapi.rs +++ b/crates/openapi/src/openapi.rs @@ -216,7 +216,7 @@ Never share your secret api keys. Keep them guarded and secure. common_utils::payout_method_utils::VenmoAdditionalData, common_types::payments::SplitPaymentsRequest, common_types::payments::StripeSplitPaymentRequest, - common_types::payments::AdyenSplitPaymentsRequest, + common_types::payments::AdyenSplitData, common_types::payments::AdyenSplitItem, common_utils::types::ChargeRefunds, common_types::refunds::SplitRefund, diff --git a/crates/openapi/src/openapi_v2.rs b/crates/openapi/src/openapi_v2.rs index e357be26649d..f2b2bf722c6b 100644 --- a/crates/openapi/src/openapi_v2.rs +++ b/crates/openapi/src/openapi_v2.rs @@ -159,7 +159,7 @@ Never share your secret api keys. Keep them guarded and secure. common_utils::payout_method_utils::VenmoAdditionalData, common_types::payments::SplitPaymentsRequest, common_types::payments::StripeSplitPaymentRequest, - common_types::payments::AdyenSplitPaymentsRequest, + common_types::payments::AdyenSplitData, common_types::payments::AdyenSplitItem, common_types::refunds::StripeSplitRefundRequest, common_utils::types::ChargeRefunds, diff --git a/crates/router/src/core/refunds.rs b/crates/router/src/core/refunds.rs index 91cc0e4e0ed6..6d9ff0dbdfb0 100644 --- a/crates/router/src/core/refunds.rs +++ b/crates/router/src/core/refunds.rs @@ -745,29 +745,81 @@ pub async fn validate_and_create_refund( let split_refunds = match payment_intent.split_payments.as_ref() { Some(common_types::payments::SplitPaymentsRequest::StripeSplitPayment(stripe_payment)) => { - if let Some(charge_id) = payment_attempt.charge_id.clone() { - let refund_request = req - .split_refunds - .clone() - .get_required_value("split_refunds")?; - - let options = validator::validate_charge_refund( - &refund_request, - &stripe_payment.charge_type, - )?; - - Some(SplitRefundsRequest::StripeSplitRefund(StripeSplitRefund { - charge_id, - charge_type: stripe_payment.charge_type.clone(), - transfer_account_id: stripe_payment.transfer_account_id.clone(), - options, - })) - } else { - None + match payment_attempt.charges { + Some(common_types::payments::ConnectorChargeResponseData::StripeSplitPayment( + stripe_split_payment_response, + )) => { + if let Some((charge_id, common_types::refunds::SplitRefund::StripeSplitRefund(refund_request))) = + stripe_split_payment_response.charge_id.zip(req.split_refunds.clone()) + { + let options = validator::validate_stripe_charge_refund( + &refund_request, + &stripe_payment.charge_type, + )?; + + Some(SplitRefundsRequest::StripeSplitRefund(StripeSplitRefund { + charge_id, + charge_type: stripe_payment.charge_type.clone(), + transfer_account_id: stripe_payment.transfer_account_id.clone(), + options, + })) + } else{ + req.split_refunds.check_value_present()? + } + } + _ => { + if let Some(charge_id) = payment_attempt.charge_id.clone() { + let refund_request = req + .split_refunds + .clone() + .get_required_value("split_refunds")?; + + let options = validator::validate_stripe_charge_refund( + &refund_request, + &stripe_payment.charge_type, + )?; + + Some(SplitRefundsRequest::StripeSplitRefund(StripeSplitRefund { + charge_id, + charge_type: stripe_payment.charge_type.clone(), + transfer_account_id: stripe_payment.transfer_account_id.clone(), + options, + })) + } else { + None + } + } } } + // Handle AdyenSplitPayment case + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_payment)) => { + match payment_attempt.charges { + // AdyenSplitPayment charge + Some(common_types::payments::ConnectorChargeResponseData::AdyenSplitPayment( + adyen_split_payment_response, + )) => { + if let Some((charge_id, common_types::refunds::SplitRefund::AdyenSplitRefund(split_refund_request))) = + adyen_split_payment_response.charge_id.zip(req.split_refunds.clone()) + { + // Validate Adyen refund + validator::validate_adyen_charge_refund( + &adyen_split_payment_response, + &split_refund_request, + )?; + + Some(SplitRefundsRequest::AdyenSplitRefund(split_refund_request)) + } else { + None + } + } + // StripeSplitPayment charge or no charges + _ => None, + } + } + // Default case _ => None, }; + // Only for initial dev and testing let refund_type = req.refund_type.unwrap_or_default(); @@ -1471,7 +1523,7 @@ pub async fn trigger_refund_execute_workflow( .clone() .get_required_value("split_refunds")?; - let options = validator::validate_charge_refund( + let options = validator::validate_stripe_charge_refund( &refund_request, &stripe_payment.charge_type, )?; @@ -1488,7 +1540,7 @@ pub async fn trigger_refund_execute_workflow( transfer_account_id: stripe_payment.transfer_account_id.clone(), options, })) - } + } //todoo _ => None, }; diff --git a/crates/router/src/core/refunds/transformers.rs b/crates/router/src/core/refunds/transformers.rs index 3d4b8702901d..c384af1ca570 100644 --- a/crates/router/src/core/refunds/transformers.rs +++ b/crates/router/src/core/refunds/transformers.rs @@ -31,10 +31,8 @@ impl TryFrom for router_request_types::SplitRefundsRequest { .attach_printable("Missing `charge_id` in PaymentAttempt.") })?; - let options = validator::validate_charge_refund( - &common_types::refunds::SplitRefund::StripeSplitRefund( - stripe_refund.clone(), - ), + let options = validator::validate_stripe_charge_refund( + &stripe_refund, &stripe_payment.charge_type, )?; @@ -47,7 +45,16 @@ impl TryFrom for router_request_types::SplitRefundsRequest { }, )) } - common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(_) => todo!(), // todooooo + common_types::payments::ConnectorChargeResponseData::AdyenSplitPayment(adyen_refund_split_payment) => { + adyen_refund_split_payment.split_items.iter().for_each(|split_item| { + if let Some(account) = &split_item.account { + if account.is_empty() { + return Err(report!(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Empty `account` in AdyenSplitItem.")); + } + } + }); + } } } } diff --git a/crates/router/src/core/refunds/validator.rs b/crates/router/src/core/refunds/validator.rs index 2387f9a3b5ff..ef4c16c73c34 100644 --- a/crates/router/src/core/refunds/validator.rs +++ b/crates/router/src/core/refunds/validator.rs @@ -146,31 +146,27 @@ pub fn validate_for_valid_refunds( } } -pub fn validate_charge_refund( - charges: &common_types::refunds::SplitRefund, +pub fn validate_stripe_charge_refund( + stripe_refund: &common_types::refunds::StripeSplitRefundRequest, charge_type: &api_enums::PaymentChargeType, ) -> RouterResult { match charge_type { api_enums::PaymentChargeType::Stripe(api_enums::StripeChargeType::Direct) => { - let common_types::refunds::SplitRefund::StripeSplitRefund(stripe_charge) = charges; - Ok(types::ChargeRefundsOptions::Direct( types::DirectChargeRefund { - revert_platform_fee: stripe_charge + revert_platform_fee: stripe_refund .revert_platform_fee .get_required_value("revert_platform_fee")?, }, )) } api_enums::PaymentChargeType::Stripe(api_enums::StripeChargeType::Destination) => { - let common_types::refunds::SplitRefund::StripeSplitRefund(stripe_charge) = charges; - Ok(types::ChargeRefundsOptions::Destination( types::DestinationChargeRefund { - revert_platform_fee: stripe_charge + revert_platform_fee: stripe_refund .revert_platform_fee .get_required_value("revert_platform_fee")?, - revert_transfer: stripe_charge + revert_transfer: stripe_refund .revert_transfer .get_required_value("revert_transfer")?, }, @@ -178,3 +174,12 @@ pub fn validate_charge_refund( } } } + +pub fn validate_adyen_charge_refund( + adyen_charge: &common_types::domain::AdyenSplitData, + adyen_refund_charge: &common_types::domain::AdyenSplitData, +) -> RouterResult<()> { + if adyen_charge.store_id != adyen_refund_charge.store_id { + Err(errors::ApiErrorResponse::InvalidDataValue { field_name: "store_id" })? + } +} From cba4871ed6873f5d4d3973eed2a44a4840fb267d Mon Sep 17 00:00:00 2001 From: AkshayaFoiger Date: Mon, 20 Jan 2025 18:10:06 +0530 Subject: [PATCH 13/21] refactor(router): add refund validations --- crates/common_enums/src/enums.rs | 4 +- crates/common_types/src/domain.rs | 2 +- crates/common_types/src/lib.rs | 2 +- crates/common_types/src/payments.rs | 5 +- crates/common_types/src/refunds.rs | 1 + .../src/router_request_types.rs | 1 + .../src/connector/adyen/transformers.rs | 166 ++++++++++++++++++ crates/router/src/connector/stripe.rs | 109 ++++++------ .../src/connector/stripe/transformers.rs | 47 +++-- crates/router/src/connector/utils.rs | 2 +- crates/router/src/core/payments/helpers.rs | 2 +- crates/router/src/core/refunds.rs | 141 ++------------- .../router/src/core/refunds/transformers.rs | 95 +++++----- crates/router/src/core/refunds/validator.rs | 122 ++++++++++--- crates/router/src/core/utils.rs | 79 +++++++++ 15 files changed, 493 insertions(+), 285 deletions(-) diff --git a/crates/common_enums/src/enums.rs b/crates/common_enums/src/enums.rs index 89682e2e5c61..e453e81208e9 100644 --- a/crates/common_enums/src/enums.rs +++ b/crates/common_enums/src/enums.rs @@ -3625,8 +3625,8 @@ pub enum FeatureStatus { strum::EnumString, ToSchema, )] -#[strum(serialize_all = "snake_case")] -#[serde(rename_all = "snake_case")] +#[strum(serialize_all = "camelCase")] +#[serde(rename_all = "camelCase")] pub enum AdyenSplitType { /// Books split amount to the specified account. BalanceAccount, diff --git a/crates/common_types/src/domain.rs b/crates/common_types/src/domain.rs index 0303626f5346..0fb940814796 100644 --- a/crates/common_types/src/domain.rs +++ b/crates/common_types/src/domain.rs @@ -31,7 +31,7 @@ pub struct AdyenSplitItem { #[schema(value_type = i64, example = 6540)] pub amount: Option, /// Defines type of split item - #[schema(value_type = AdyenSplitType, example = "balance_account")] + #[schema(value_type = AdyenSplitType, example = "BalanceAccount")] pub split_type: enums::AdyenSplitType, /// The unique identifier of the account to which the split amount is allocated. pub account: Option, diff --git a/crates/common_types/src/lib.rs b/crates/common_types/src/lib.rs index 810d4a7e7006..6139ddff16ae 100644 --- a/crates/common_types/src/lib.rs +++ b/crates/common_types/src/lib.rs @@ -2,7 +2,7 @@ #![warn(missing_docs, missing_debug_implementations)] +pub mod domain; pub mod payment_methods; pub mod payments; pub mod refunds; -pub mod domain; diff --git a/crates/common_types/src/payments.rs b/crates/common_types/src/payments.rs index 98f922beefd9..58801fc45f69 100644 --- a/crates/common_types/src/payments.rs +++ b/crates/common_types/src/payments.rs @@ -1,12 +1,13 @@ //! Payment related types -use crate::domain as domain_types; use common_enums::enums; use common_utils::{impl_to_sql_from_sql_json, types::MinorUnit}; use diesel::{sql_types::Jsonb, AsExpression, FromSqlRow}; use serde::{Deserialize, Serialize}; use utoipa::ToSchema; +use crate::domain as domain_types; + #[derive( Serialize, Deserialize, Debug, Clone, PartialEq, Eq, FromSqlRow, AsExpression, ToSchema, )] @@ -65,8 +66,6 @@ pub struct StripeChargeResponseData { } impl_to_sql_from_sql_json!(StripeChargeResponseData); - - /// Charge Information #[derive( Serialize, Deserialize, Debug, Clone, PartialEq, Eq, FromSqlRow, AsExpression, ToSchema, diff --git a/crates/common_types/src/refunds.rs b/crates/common_types/src/refunds.rs index d25fad10bee8..14223d32a47b 100644 --- a/crates/common_types/src/refunds.rs +++ b/crates/common_types/src/refunds.rs @@ -4,6 +4,7 @@ use common_utils::impl_to_sql_from_sql_json; use diesel::{sql_types::Jsonb, AsExpression, FromSqlRow}; use serde::{Deserialize, Serialize}; use utoipa::ToSchema; + use crate::domain as domain_types; #[derive( diff --git a/crates/hyperswitch_domain_models/src/router_request_types.rs b/crates/hyperswitch_domain_models/src/router_request_types.rs index aa9fb2b5f1f0..4153f6f2343f 100644 --- a/crates/hyperswitch_domain_models/src/router_request_types.rs +++ b/crates/hyperswitch_domain_models/src/router_request_types.rs @@ -624,6 +624,7 @@ pub struct RefundIntegrityObject { #[derive(Debug, serde::Deserialize, Clone)] pub enum SplitRefundsRequest { StripeSplitRefund(StripeSplitRefund), + AdyenSplitRefund(common_types::domain::AdyenSplitData), } #[derive(Debug, serde::Deserialize, Clone)] diff --git a/crates/router/src/connector/adyen/transformers.rs b/crates/router/src/connector/adyen/transformers.rs index 7d1e5077936d..ba8452cf7512 100644 --- a/crates/router/src/connector/adyen/transformers.rs +++ b/crates/router/src/connector/adyen/transformers.rs @@ -171,6 +171,19 @@ pub struct AdyenPaymentRequest<'a> { channel: Option, metadata: Option, merchant_order_reference: Option, + splits: Option>, + store_id: Option, +} + +#[derive(Debug, Serialize)] +#[serde(rename_all = "camelCase")] +struct AdyenSplitData { + amount: Option, + #[serde(rename = "type")] + split_type: common_enums::AdyenSplitType, + account: Option, + reference: Option, + description: Option, } #[serde_with::skip_serializing_none] @@ -2754,6 +2767,17 @@ impl } } // }?; + + let (store_id, splits) = item + .router_data + .request + .split_payments + .as_ref() + .and_then(|split_payment_data| { + get_adyen_split_request(split_payment_data, item.router_data.request.currency) + }) + .unwrap_or((None, None)); + Ok(AdyenPaymentRequest { amount, merchant_account: auth_type.merchant_account, @@ -2781,6 +2805,8 @@ impl shopper_ip: item.router_data.request.get_ip_address_as_optional(), metadata: item.router_data.request.metadata.clone().map(Into::into), merchant_order_reference: item.router_data.request.merchant_order_reference_id.clone(), + store_id, + splits, }) } } @@ -2817,6 +2843,15 @@ impl let payment_method = AdyenPaymentMethod::try_from((card_data, card_holder_name))?; let shopper_email = item.router_data.get_optional_billing_email(); let shopper_name = get_shopper_name(item.router_data.get_optional_billing()); + let (store_id, splits) = item + .router_data + .request + .split_payments + .as_ref() + .and_then(|split_payment_data| { + get_adyen_split_request(split_payment_data, item.router_data.request.currency) + }) + .unwrap_or((None, None)); Ok(AdyenPaymentRequest { amount, @@ -2845,6 +2880,8 @@ impl shopper_ip: item.router_data.request.get_ip_address_as_optional(), metadata: item.router_data.request.metadata.clone().map(Into::into), merchant_order_reference: item.router_data.request.merchant_order_reference_id.clone(), + store_id, + splits, }) } } @@ -2874,6 +2911,15 @@ impl let return_url = item.router_data.request.get_return_url()?; let payment_method = AdyenPaymentMethod::try_from((bank_debit_data, item.router_data))?; let country_code = get_country_code(item.router_data.get_optional_billing()); + let (store_id, splits) = item + .router_data + .request + .split_payments + .as_ref() + .and_then(|split_payment_data| { + get_adyen_split_request(split_payment_data, item.router_data.request.currency) + }) + .unwrap_or((None, None)); let request = AdyenPaymentRequest { amount, merchant_account: auth_type.merchant_account, @@ -2901,6 +2947,8 @@ impl shopper_ip: item.router_data.request.get_ip_address_as_optional(), metadata: item.router_data.request.metadata.clone().map(Into::into), merchant_order_reference: item.router_data.request.merchant_order_reference_id.clone(), + store_id, + splits, }; Ok(request) } @@ -2933,6 +2981,15 @@ impl let billing_address = get_address_info(item.router_data.get_optional_billing()).and_then(Result::ok); let shopper_name = get_shopper_name(item.router_data.get_optional_billing()); + let (store_id, splits) = item + .router_data + .request + .split_payments + .as_ref() + .and_then(|split_payment_data| { + get_adyen_split_request(split_payment_data, item.router_data.request.currency) + }) + .unwrap_or((None, None)); let request = AdyenPaymentRequest { amount, @@ -2961,6 +3018,8 @@ impl shopper_ip: item.router_data.request.get_ip_address_as_optional(), metadata: item.router_data.request.metadata.clone().map(Into::into), merchant_order_reference: item.router_data.request.merchant_order_reference_id.clone(), + store_id, + splits, }; Ok(request) } @@ -2986,6 +3045,15 @@ impl let shopper_interaction = AdyenShopperInteraction::from(item.router_data); let payment_method = AdyenPaymentMethod::try_from((bank_transfer_data, item.router_data))?; let return_url = item.router_data.request.get_return_url()?; + let (store_id, splits) = item + .router_data + .request + .split_payments + .as_ref() + .and_then(|split_payment_data| { + get_adyen_split_request(split_payment_data, item.router_data.request.currency) + }) + .unwrap_or((None, None)); let request = AdyenPaymentRequest { amount, merchant_account: auth_type.merchant_account, @@ -3013,6 +3081,8 @@ impl shopper_ip: item.router_data.request.get_ip_address_as_optional(), metadata: item.router_data.request.metadata.clone().map(Into::into), merchant_order_reference: item.router_data.request.merchant_order_reference_id.clone(), + store_id, + splits, }; Ok(request) } @@ -3038,6 +3108,16 @@ impl let shopper_interaction = AdyenShopperInteraction::from(item.router_data); let return_url = item.router_data.request.get_router_return_url()?; let payment_method = AdyenPaymentMethod::try_from(gift_card_data)?; + let (store_id, splits) = item + .router_data + .request + .split_payments + .as_ref() + .and_then(|split_payment_data| { + get_adyen_split_request(split_payment_data, item.router_data.request.currency) + }) + .unwrap_or((None, None)); + let request = AdyenPaymentRequest { amount, merchant_account: auth_type.merchant_account, @@ -3065,6 +3145,8 @@ impl shopper_ip: item.router_data.request.get_ip_address_as_optional(), metadata: item.router_data.request.metadata.clone().map(Into::into), merchant_order_reference: item.router_data.request.merchant_order_reference_id.clone(), + store_id, + splits, }; Ok(request) } @@ -3101,6 +3183,15 @@ impl let line_items = Some(get_line_items(item)); let billing_address = get_address_info(item.router_data.get_optional_billing()).and_then(Result::ok); + let (store_id, splits) = item + .router_data + .request + .split_payments + .as_ref() + .and_then(|split_payment_data| { + get_adyen_split_request(split_payment_data, item.router_data.request.currency) + }) + .unwrap_or((None, None)); Ok(AdyenPaymentRequest { amount, @@ -3129,6 +3220,8 @@ impl shopper_ip: item.router_data.request.get_ip_address_as_optional(), metadata: item.router_data.request.metadata.clone().map(Into::into), merchant_order_reference: item.router_data.request.merchant_order_reference_id.clone(), + store_id, + splits, }) } } @@ -3219,6 +3312,15 @@ impl } else { None }; + let (store_id, splits) = item + .router_data + .request + .split_payments + .as_ref() + .and_then(|split_payment_data| { + get_adyen_split_request(split_payment_data, item.router_data.request.currency) + }) + .unwrap_or((None, None)); Ok(AdyenPaymentRequest { amount, merchant_account: auth_type.merchant_account, @@ -3246,6 +3348,8 @@ impl shopper_ip: item.router_data.request.get_ip_address_as_optional(), metadata: item.router_data.request.metadata.clone().map(Into::into), merchant_order_reference: item.router_data.request.merchant_order_reference_id.clone(), + store_id, + splits, }) } } @@ -3295,6 +3399,16 @@ impl &billing_address, &delivery_address, ))?; + let (store_id, splits) = item + .router_data + .request + .split_payments + .as_ref() + .and_then(|split_payment_data| { + get_adyen_split_request(split_payment_data, item.router_data.request.currency) + }) + .unwrap_or((None, None)); + Ok(AdyenPaymentRequest { amount, merchant_account: auth_type.merchant_account, @@ -3322,6 +3436,8 @@ impl shopper_ip: item.router_data.request.get_ip_address_as_optional(), metadata: item.router_data.request.metadata.clone().map(Into::into), merchant_order_reference: item.router_data.request.merchant_order_reference_id.clone(), + store_id, + splits, }) } } @@ -3355,6 +3471,16 @@ impl })? .number .to_owned(); + let (store_id, splits) = item + .router_data + .request + .split_payments + .as_ref() + .and_then(|split_payment_data| { + get_adyen_split_request(split_payment_data, item.router_data.request.currency) + }) + .unwrap_or((None, None)); + Ok(AdyenPaymentRequest { amount, merchant_account: auth_type.merchant_account, @@ -3382,6 +3508,8 @@ impl shopper_ip: item.router_data.request.get_ip_address_as_optional(), metadata: item.router_data.request.metadata.clone().map(Into::into), merchant_order_reference: item.router_data.request.merchant_order_reference_id.clone(), + store_id, + splits, }) } } @@ -3397,6 +3525,33 @@ impl TryFrom<&types::PaymentsCancelRouterData> for AdyenCancelRequest { } } +fn get_adyen_split_request( + item: &common_types::payments::SplitPaymentsRequest, + currency: common_enums::enums::Currency, +) -> Option<(Option, Option>)> { + match item { + common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(split_payment_data) => { + let splits: Vec = split_payment_data + .split_items + .iter() + .map(|split_item| { + let amount = split_item.amount.map(|value| Amount { currency, value }); + AdyenSplitData { + amount, + reference: split_item.reference.clone(), + split_type: split_item.split_type.clone(), + account: split_item.account.clone(), + description: split_item.description.clone(), + } + }) + .collect(); + + Some((split_payment_data.store_id.clone(), Some(splits))) + } + _ => None, + } +} + impl TryFrom> for types::PaymentsCancelRouterData { @@ -5458,6 +5613,15 @@ impl .unwrap_or_default(), eci: Some("02".to_string()), }; + let (store_id, splits) = item + .router_data + .request + .split_payments + .as_ref() + .and_then(|split_payment_data| { + get_adyen_split_request(split_payment_data, item.router_data.request.currency) + }) + .unwrap_or((None, None)); Ok(AdyenPaymentRequest { amount, @@ -5486,6 +5650,8 @@ impl metadata: item.router_data.request.metadata.clone().map(Into::into), merchant_order_reference: item.router_data.request.merchant_order_reference_id.clone(), mpi_data: Some(mpi_data), + store_id, + splits, }) } } diff --git a/crates/router/src/connector/stripe.rs b/crates/router/src/connector/stripe.rs index 2771666d8089..66e20e54616e 100644 --- a/crates/router/src/connector/stripe.rs +++ b/crates/router/src/connector/stripe.rs @@ -768,13 +768,13 @@ impl if let Some(common_types::payments::SplitPaymentsRequest::StripeSplitPayment( stripe_split_payment, - )) = &req.request.split_payments { - - transformers::transform_headers_for_connect_platform( - stripe_split_payment.charge_type.clone(), - stripe_split_payment.transfer_account_id.clone(), - &mut header, - ); + )) = &req.request.split_payments + { + transformers::transform_headers_for_connect_platform( + stripe_split_payment.charge_type.clone(), + stripe_split_payment.transfer_account_id.clone(), + &mut header, + ); } Ok(header) } @@ -942,21 +942,20 @@ impl if let Some(common_types::payments::SplitPaymentsRequest::StripeSplitPayment( stripe_split_payment, - )) = &req.request.split_payments { - if stripe_split_payment.charge_type - == api::enums::PaymentChargeType::Stripe( - api::enums::StripeChargeType::Direct, - ) - { - let mut customer_account_header = vec![( - headers::STRIPE_COMPATIBLE_CONNECT_ACCOUNT.to_string(), - stripe_split_payment - .transfer_account_id - .clone() - .into_masked(), - )]; - header.append(&mut customer_account_header); - } + )) = &req.request.split_payments + { + if stripe_split_payment.charge_type + == api::enums::PaymentChargeType::Stripe(api::enums::StripeChargeType::Direct) + { + let mut customer_account_header = vec![( + headers::STRIPE_COMPATIBLE_CONNECT_ACCOUNT.to_string(), + stripe_split_payment + .transfer_account_id + .clone() + .into_masked(), + )]; + header.append(&mut customer_account_header); + } } Ok(header) } @@ -1477,22 +1476,20 @@ impl services::ConnectorIntegration { - match &stripe_split_refund.charge_type { - api::enums::PaymentChargeType::Stripe(stripe_charge) => { - if stripe_charge == &api::enums::StripeChargeType::Direct { - let mut customer_account_header = vec![( - headers::STRIPE_COMPATIBLE_CONNECT_ACCOUNT.to_string(), - stripe_split_refund - .transfer_account_id - .clone() - .into_masked(), - )]; - header.append(&mut customer_account_header); - } - } + if let Some(SplitRefundsRequest::StripeSplitRefund(ref stripe_split_refund)) = + req.request.split_refunds.as_ref() + { + match &stripe_split_refund.charge_type { + api::enums::PaymentChargeType::Stripe(stripe_charge) => { + if stripe_charge == &api::enums::StripeChargeType::Direct { + let mut customer_account_header = vec![( + headers::STRIPE_COMPATIBLE_CONNECT_ACCOUNT.to_string(), + stripe_split_refund + .transfer_account_id + .clone() + .into_masked(), + )]; + header.append(&mut customer_account_header); } } } @@ -1523,15 +1520,15 @@ impl services::ConnectorIntegration RequestContent::FormUrlEncoded(Box::new(stripe::RefundRequest::try_from(( - req, - refund_amount, - ))?)), - Some(split_refunds) => match split_refunds { - SplitRefundsRequest::StripeSplitRefund(_) => RequestContent::FormUrlEncoded( - Box::new(stripe::ChargeRefundRequest::try_from(req)?), - ), - }, + Some(SplitRefundsRequest::AdyenSplitRefund(_)) | None => { + RequestContent::FormUrlEncoded(Box::new(stripe::RefundRequest::try_from(( + req, + refund_amount, + ))?)) + } + Some(SplitRefundsRequest::StripeSplitRefund(_)) => RequestContent::FormUrlEncoded( + Box::new(stripe::ChargeRefundRequest::try_from(req)?), + ), }; Ok(request_body) } @@ -1646,16 +1643,14 @@ impl services::ConnectorIntegration { - transformers::transform_headers_for_connect_platform( - stripe_refund.charge_type.clone(), - stripe_refund.transfer_account_id.clone(), - &mut header, - ); - } - } + if let Some(SplitRefundsRequest::StripeSplitRefund(ref stripe_refund)) = + req.request.split_refunds.as_ref() + { + transformers::transform_headers_for_connect_platform( + stripe_refund.charge_type.clone(), + stripe_refund.transfer_account_id.clone(), + &mut header, + ); } Ok(header) } diff --git a/crates/router/src/connector/stripe/transformers.rs b/crates/router/src/connector/stripe/transformers.rs index eb123194f268..62d39326b00c 100644 --- a/crates/router/src/connector/stripe/transformers.rs +++ b/crates/router/src/connector/stripe/transformers.rs @@ -1953,8 +1953,9 @@ impl TryFrom<(&types::PaymentsAuthorizeRouterData, MinorUnit)> for PaymentIntent }; (charges, None) } - Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(_)) - | None => (None, item.connector_customer.to_owned().map(Secret::new)), + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(_)) | None => { + (None, item.connector_customer.to_owned().map(Secret::new)) + } }; Ok(Self { @@ -2452,7 +2453,7 @@ fn extract_payment_method_connector_response_from_latest_attempt( impl TryFrom> for types::RouterData - where +where T: connector_util::SplitPaymentData, { type Error = error_stack::Report; @@ -2516,7 +2517,7 @@ impl StripeChargeEnum::ChargeObject(charge) => charge.id.clone(), }) .and_then(|charge_id| construct_charge_response(charge_id, &item.data.request)); - + Ok(types::PaymentsResponseData::TransactionResponse { resource_id: types::ResponseId::ConnectorTransactionId(item.response.id.clone()), redirection_data: Box::new(redirection_data), @@ -2614,7 +2615,7 @@ pub fn get_connector_metadata( impl TryFrom> for types::RouterData - where +where T: connector_util::SplitPaymentData, { type Error = error_stack::Report; @@ -3068,6 +3069,11 @@ impl TryFrom<&types::RefundsRouterData> for ChargeRefundRequest { }, }) } + types::SplitRefundsRequest::AdyenSplitRefund(_) => { + Err(errors::ConnectorError::MissingRequiredField { + field_name: "stripe_split_refund", + })? + } }, } } @@ -4327,17 +4333,24 @@ pub fn construct_charge_response( ) -> Option where T: connector_util::SplitPaymentData, - { +{ let charge_request = request.get_split_payment_data(); - if let Some(common_types::payments::SplitPaymentsRequest::StripeSplitPayment(stripe_split_payment)) = charge_request { - let stripe_charge_response = common_types::payments::StripeChargeResponseData{ - charge_id: Some(charge_id), - charge_type: stripe_split_payment.charge_type, - application_fees: stripe_split_payment.application_fees, - transfer_account_id: stripe_split_payment.transfer_account_id, - }; - Some(common_types::payments::ConnectorChargeResponseData::StripeSplitPayment(stripe_charge_response)) -} else { - None + if let Some(common_types::payments::SplitPaymentsRequest::StripeSplitPayment( + stripe_split_payment, + )) = charge_request + { + let stripe_charge_response = common_types::payments::StripeChargeResponseData { + charge_id: Some(charge_id), + charge_type: stripe_split_payment.charge_type, + application_fees: stripe_split_payment.application_fees, + transfer_account_id: stripe_split_payment.transfer_account_id, + }; + Some( + common_types::payments::ConnectorChargeResponseData::StripeSplitPayment( + stripe_charge_response, + ), + ) + } else { + None + } } -} \ No newline at end of file diff --git a/crates/router/src/connector/utils.rs b/crates/router/src/connector/utils.rs index 32d60fc5b5f6..a72a1ec18bde 100644 --- a/crates/router/src/connector/utils.rs +++ b/crates/router/src/connector/utils.rs @@ -783,7 +783,7 @@ impl SplitPaymentData for types::PaymentsSyncData { impl SplitPaymentData for PaymentsCancelData { fn get_split_payment_data(&self) -> Option { - None + None } } diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index 90c9b27e971a..19aba7e09e21 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -6355,4 +6355,4 @@ pub fn validate_platform_request_for_marketplace( None => (), } Ok(()) -} \ No newline at end of file +} diff --git a/crates/router/src/core/refunds.rs b/crates/router/src/core/refunds.rs index 6d9ff0dbdfb0..f61859039f4c 100644 --- a/crates/router/src/core/refunds.rs +++ b/crates/router/src/core/refunds.rs @@ -13,8 +13,7 @@ use common_utils::{ use diesel_models::process_tracker::business_status; use error_stack::{report, ResultExt}; use hyperswitch_domain_models::{ - router_data::ErrorResponse, - router_request_types::{SplitRefundsRequest, StripeSplitRefund}, + router_data::ErrorResponse, router_request_types::SplitRefundsRequest, }; use hyperswitch_interfaces::integrity::{CheckIntegrity, FlowIntegrity, GetIntegrityObject}; use router_env::{instrument, tracing}; @@ -466,18 +465,12 @@ pub async fn refund_retrieve_core( .await .transpose()?; - let split_refunds_req: Option = payment_attempt - .charges - .clone() - .zip(refund.split_refunds.clone()) - .map(|(split_payments, split_refunds)| { - SplitRefundsRequest::try_from(SplitRefundInput { - refund_request: split_refunds, - payment_charges: split_payments, - charge_id: payment_attempt.charge_id.clone(), - }) - }) - .transpose()?; + let split_refunds_req = core_utils::get_split_refunds(SplitRefundInput { + split_payment_request: payment_intent.split_payments.clone(), + payment_charges: payment_attempt.charges.clone(), + charge_id: payment_attempt.charge_id.clone(), + refund_request: refund.split_refunds.clone(), + })?; let response = if should_call_refund(&refund, request.force_sync.unwrap_or(false)) { Box::pin(sync_refund_with_gateway( @@ -742,84 +735,12 @@ pub async fn validate_and_create_refund( creds_identifier: Option, ) -> RouterResult { let db = &*state.store; - - let split_refunds = match payment_intent.split_payments.as_ref() { - Some(common_types::payments::SplitPaymentsRequest::StripeSplitPayment(stripe_payment)) => { - match payment_attempt.charges { - Some(common_types::payments::ConnectorChargeResponseData::StripeSplitPayment( - stripe_split_payment_response, - )) => { - if let Some((charge_id, common_types::refunds::SplitRefund::StripeSplitRefund(refund_request))) = - stripe_split_payment_response.charge_id.zip(req.split_refunds.clone()) - { - let options = validator::validate_stripe_charge_refund( - &refund_request, - &stripe_payment.charge_type, - )?; - - Some(SplitRefundsRequest::StripeSplitRefund(StripeSplitRefund { - charge_id, - charge_type: stripe_payment.charge_type.clone(), - transfer_account_id: stripe_payment.transfer_account_id.clone(), - options, - })) - } else{ - req.split_refunds.check_value_present()? - } - } - _ => { - if let Some(charge_id) = payment_attempt.charge_id.clone() { - let refund_request = req - .split_refunds - .clone() - .get_required_value("split_refunds")?; - - let options = validator::validate_stripe_charge_refund( - &refund_request, - &stripe_payment.charge_type, - )?; - - Some(SplitRefundsRequest::StripeSplitRefund(StripeSplitRefund { - charge_id, - charge_type: stripe_payment.charge_type.clone(), - transfer_account_id: stripe_payment.transfer_account_id.clone(), - options, - })) - } else { - None - } - } - } - } - // Handle AdyenSplitPayment case - Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_payment)) => { - match payment_attempt.charges { - // AdyenSplitPayment charge - Some(common_types::payments::ConnectorChargeResponseData::AdyenSplitPayment( - adyen_split_payment_response, - )) => { - if let Some((charge_id, common_types::refunds::SplitRefund::AdyenSplitRefund(split_refund_request))) = - adyen_split_payment_response.charge_id.zip(req.split_refunds.clone()) - { - // Validate Adyen refund - validator::validate_adyen_charge_refund( - &adyen_split_payment_response, - &split_refund_request, - )?; - - Some(SplitRefundsRequest::AdyenSplitRefund(split_refund_request)) - } else { - None - } - } - // StripeSplitPayment charge or no charges - _ => None, - } - } - // Default case - _ => None, - }; - + let split_refunds = core_utils::get_split_refunds(SplitRefundInput { + split_payment_request: payment_intent.split_payments.clone(), + payment_charges: payment_attempt.charges.clone(), + charge_id: payment_attempt.charge_id.clone(), + refund_request: req.split_refunds.clone(), + })?; // Only for initial dev and testing let refund_type = req.refund_type.unwrap_or_default(); @@ -1513,36 +1434,12 @@ pub async fn trigger_refund_execute_workflow( ) .await .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?; - - let split_refunds = match payment_intent.split_payments.as_ref() { - Some(common_types::payments::SplitPaymentsRequest::StripeSplitPayment( - stripe_payment, - )) => { - let refund_request = refund - .split_refunds - .clone() - .get_required_value("split_refunds")?; - - let options = validator::validate_stripe_charge_refund( - &refund_request, - &stripe_payment.charge_type, - )?; - - let charge_id = payment_attempt.charge_id.clone().ok_or_else(|| { - report!(errors::ApiErrorResponse::InternalServerError).attach_printable( - "Transaction is invalid. Missing field \"charge_id\" in payment_attempt.", - ) - })?; - - Some(SplitRefundsRequest::StripeSplitRefund(StripeSplitRefund { - charge_id, - charge_type: stripe_payment.charge_type.clone(), - transfer_account_id: stripe_payment.transfer_account_id.clone(), - options, - })) - } //todoo - _ => None, - }; + let split_refunds = core_utils::get_split_refunds(SplitRefundInput { + split_payment_request: payment_intent.split_payments.clone(), + payment_charges: payment_attempt.charges.clone(), + charge_id: payment_attempt.charge_id.clone(), + refund_request: refund.split_refunds.clone(), + })?; //trigger refund request to gateway let updated_refund = Box::pin(trigger_refund_to_gateway( diff --git a/crates/router/src/core/refunds/transformers.rs b/crates/router/src/core/refunds/transformers.rs index c384af1ca570..7235068c947d 100644 --- a/crates/router/src/core/refunds/transformers.rs +++ b/crates/router/src/core/refunds/transformers.rs @@ -1,62 +1,47 @@ -use error_stack::{report, Report}; -use hyperswitch_domain_models::router_request_types; - -use super::validator; -use crate::core::errors; - pub struct SplitRefundInput { - pub refund_request: common_types::refunds::SplitRefund, - pub payment_charges: common_types::payments::ConnectorChargeResponseData, + pub refund_request: Option, + pub payment_charges: Option, + pub split_payment_request: Option, pub charge_id: Option, } -impl TryFrom for router_request_types::SplitRefundsRequest { - type Error = Report; +// impl TryFrom for router_request_types::SplitRefundsRequest { +// type Error = Report; - fn try_from(value: SplitRefundInput) -> Result { - let SplitRefundInput { - refund_request, - payment_charges, - charge_id, - } = value; +// fn try_from(value: SplitRefundInput) -> Result { +// let SplitRefundInput { +// refund_request, +// payment_charges, +// charge_id, +// } = value; - match refund_request { - common_types::refunds::SplitRefund::StripeSplitRefund(stripe_refund) => { - match payment_charges { - common_types::payments::ConnectorChargeResponseData::StripeSplitPayment( - stripe_payment, - ) => { - let charge_id = stripe_payment.charge_id.or(charge_id).ok_or_else(|| { - report!(errors::ApiErrorResponse::InternalServerError) - .attach_printable("Missing `charge_id` in PaymentAttempt.") - })?; +// match refund_request { +// common_types::refunds::SplitRefund::StripeSplitRefund(stripe_refund) => { +// if let Some((split_charge_id, options)) = +// validator::validate_stripe_charge_refund( +// &charge_id, +// &Some(refund_request), +// None, +// &Some(payment_charges), +// )? { - let options = validator::validate_stripe_charge_refund( - &stripe_refund, - &stripe_payment.charge_type, - )?; - - Ok(Self::StripeSplitRefund( - router_request_types::StripeSplitRefund { - charge_id, // Use `charge_id` from `PaymentAttempt` - transfer_account_id: stripe_payment.transfer_account_id, - charge_type: stripe_payment.charge_type, - options, - }, - )) - } - common_types::payments::ConnectorChargeResponseData::AdyenSplitPayment(adyen_refund_split_payment) => { - adyen_refund_split_payment.split_items.iter().for_each(|split_item| { - if let Some(account) = &split_item.account { - if account.is_empty() { - return Err(report!(errors::ApiErrorResponse::InternalServerError) - .attach_printable("Empty `account` in AdyenSplitItem.")); - } - } - }); - } - } - } - } - } -} +// Ok(Self::StripeSplitRefund( +// router_request_types::StripeSplitRefund { +// charge_id: split_charge_id.clone(), +// transfer_account_id: stripe_refund.transfer_account_id.clone(), +// charge_type: stripe_refund.charge_type.clone(), +// options, +// }, +// )) +// } else { +// None +// } +// } +// common_types::refunds::SplitRefund::AdyenSplitRefund(adyen_refund) => { +// Ok(Self::AdyenSplitRefund( +// adyen_refund, +// )) +// } +// } +// } +// } diff --git a/crates/router/src/core/refunds/validator.rs b/crates/router/src/core/refunds/validator.rs index ef4c16c73c34..1ea288bba413 100644 --- a/crates/router/src/core/refunds/validator.rs +++ b/crates/router/src/core/refunds/validator.rs @@ -147,39 +147,111 @@ pub fn validate_for_valid_refunds( } pub fn validate_stripe_charge_refund( - stripe_refund: &common_types::refunds::StripeSplitRefundRequest, - charge_type: &api_enums::PaymentChargeType, + charge_type_option: Option, + split_refund_request: &Option, ) -> RouterResult { - match charge_type { + let charge_type = charge_type_option.ok_or_else(|| { + report!(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Missing `charge_type` in PaymentAttempt.") + })?; + + let refund_request = match split_refund_request { + Some(common_types::refunds::SplitRefund::StripeSplitRefund(stripe_split_refund)) => { + stripe_split_refund + } + _ => Err(errors::ApiErrorResponse::MissingRequiredField { + field_name: "stripe_split_refund", + })?, + }; + + let options = match charge_type { api_enums::PaymentChargeType::Stripe(api_enums::StripeChargeType::Direct) => { - Ok(types::ChargeRefundsOptions::Direct( - types::DirectChargeRefund { - revert_platform_fee: stripe_refund - .revert_platform_fee - .get_required_value("revert_platform_fee")?, - }, - )) + types::ChargeRefundsOptions::Direct(types::DirectChargeRefund { + revert_platform_fee: refund_request + .revert_platform_fee + .get_required_value("revert_platform_fee")?, + }) } api_enums::PaymentChargeType::Stripe(api_enums::StripeChargeType::Destination) => { - Ok(types::ChargeRefundsOptions::Destination( - types::DestinationChargeRefund { - revert_platform_fee: stripe_refund - .revert_platform_fee - .get_required_value("revert_platform_fee")?, - revert_transfer: stripe_refund - .revert_transfer - .get_required_value("revert_transfer")?, - }, - )) + types::ChargeRefundsOptions::Destination(types::DestinationChargeRefund { + revert_platform_fee: refund_request + .revert_platform_fee + .get_required_value("revert_platform_fee")?, + revert_transfer: refund_request + .revert_transfer + .get_required_value("revert_transfer")?, + }) } - } + }; + + Ok(options) } pub fn validate_adyen_charge_refund( - adyen_charge: &common_types::domain::AdyenSplitData, - adyen_refund_charge: &common_types::domain::AdyenSplitData, + adyen_split_payment_response: &common_types::domain::AdyenSplitData, + adyen_split_refund_request: &common_types::domain::AdyenSplitData, ) -> RouterResult<()> { - if adyen_charge.store_id != adyen_refund_charge.store_id { - Err(errors::ApiErrorResponse::InvalidDataValue { field_name: "store_id" })? + if adyen_split_refund_request.store_id != adyen_split_payment_response.store_id { + return Err(report!(errors::ApiErrorResponse::InvalidDataValue { + field_name: "store_id", + })); + } + + for refund_split_item in adyen_split_refund_request.split_items.iter() { + match &refund_split_item.reference { + Some(refund_split_reference) => { + let matching_payment_split_item = adyen_split_payment_response + .split_items + .iter() + .find(|payment_split_item| { + Some(refund_split_reference.clone()) == payment_split_item.reference + }); + + if let Some(payment_split_item) = matching_payment_split_item { + if let Some(refund_amount) = refund_split_item.amount { + if let Some(payment_amount) = payment_split_item.amount { + if refund_amount > payment_amount { + return Err(report!( + errors::ApiErrorResponse::InvalidRequestData { + message: format!( + "Invalid refund amount for split item, reference: {}", + refund_split_reference + ), + } + )); + } + } + } + + if refund_split_item.account != payment_split_item.account { + return Err(report!(errors::ApiErrorResponse::InvalidRequestData { + message: format!( + "Invalid refund account for split item, reference: {}", + refund_split_reference + ), + })); + } + + if refund_split_item.split_type != payment_split_item.split_type { + return Err(report!(errors::ApiErrorResponse::InvalidRequestData { + message: format!( + "Invalid refund split_type for split item, reference: {}", + refund_split_reference + ), + })); + } + } else { + return Err(report!(errors::ApiErrorResponse::InvalidRequestData { + message: format!( + "No matching payment split item found for reference: {}", + refund_split_reference + ), + })); + } + } + None => (), + } } + + Ok(()) } diff --git a/crates/router/src/core/utils.rs b/crates/router/src/core/utils.rs index 951d3c003fd2..a7a1114b0760 100644 --- a/crates/router/src/core/utils.rs +++ b/crates/router/src/core/utils.rs @@ -450,6 +450,85 @@ pub fn validate_uuid(uuid: String, key: &str) -> Result RouterResult> { + match split_refund_input.split_payment_request.as_ref() { + Some(common_types::payments::SplitPaymentsRequest::StripeSplitPayment(stripe_payment)) => { + let (charge_id_option, charge_type_option) = match ( + &split_refund_input.payment_charges, + &split_refund_input.split_payment_request, + ) { + ( + Some(common_types::payments::ConnectorChargeResponseData::StripeSplitPayment( + stripe_split_payment_response, + )), + _, + ) => ( + stripe_split_payment_response.charge_id.clone(), + Some(stripe_split_payment_response.charge_type.clone()), + ), + ( + _, + Some(common_types::payments::SplitPaymentsRequest::StripeSplitPayment( + stripe_split_payment_request, + )), + ) => ( + split_refund_input.charge_id, + Some(stripe_split_payment_request.charge_type.clone()), + ), + (_, _) => (None, None), + }; + + if let Some(charge_id) = charge_id_option { + let options = super::refunds::validator::validate_stripe_charge_refund( + charge_type_option, + &split_refund_input.refund_request, + )?; + + Ok(Some( + router_request_types::SplitRefundsRequest::StripeSplitRefund( + router_request_types::StripeSplitRefund { + charge_id, + charge_type: stripe_payment.charge_type.clone(), + transfer_account_id: stripe_payment.transfer_account_id.clone(), + options, + }, + ), + )) + } else { + Ok(None) + } + } + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(_)) => { + match &split_refund_input.payment_charges { + Some(common_types::payments::ConnectorChargeResponseData::AdyenSplitPayment( + adyen_split_payment_response, + )) => { + if let Some(common_types::refunds::SplitRefund::AdyenSplitRefund( + split_refund_request, + )) = split_refund_input.refund_request.clone() + { + super::refunds::validator::validate_adyen_charge_refund( + &adyen_split_payment_response, + &split_refund_request, + )?; + + Ok(Some( + router_request_types::SplitRefundsRequest::AdyenSplitRefund( + split_refund_request, + ), + )) + } else { + Ok(None) + } + } + _ => Ok(None), + } + } + _ => Ok(None), + } +} #[cfg(test)] mod tests { #![allow(clippy::expect_used)] From 2998cd5940ce35170f1faaa51ac6bc4f20f56408 Mon Sep 17 00:00:00 2001 From: AkshayaFoiger Date: Mon, 20 Jan 2025 20:41:36 +0530 Subject: [PATCH 14/21] refactor(router): add store and splits to adyen request --- crates/common_types/src/domain.rs | 2 +- .../src/connector/adyen/transformers.rs | 302 ++++++++++-------- crates/router/src/connector/utils.rs | 9 +- crates/router/src/core/payments/helpers.rs | 2 +- .../router/src/core/refunds/transformers.rs | 43 +-- crates/router/src/core/refunds/validator.rs | 4 +- 6 files changed, 187 insertions(+), 175 deletions(-) diff --git a/crates/common_types/src/domain.rs b/crates/common_types/src/domain.rs index 0fb940814796..875fc6cb4e24 100644 --- a/crates/common_types/src/domain.rs +++ b/crates/common_types/src/domain.rs @@ -14,7 +14,7 @@ use utoipa::ToSchema; /// Fee information for Split Payments to be charged on the payment being collected for Adyen pub struct AdyenSplitData { /// The store identifier - pub store_id: Option, + pub store: Option, /// Data for the split items pub split_items: Vec, } diff --git a/crates/router/src/connector/adyen/transformers.rs b/crates/router/src/connector/adyen/transformers.rs index ba8452cf7512..eab6e0550e97 100644 --- a/crates/router/src/connector/adyen/transformers.rs +++ b/crates/router/src/connector/adyen/transformers.rs @@ -172,10 +172,10 @@ pub struct AdyenPaymentRequest<'a> { metadata: Option, merchant_order_reference: Option, splits: Option>, - store_id: Option, + store: Option, } -#[derive(Debug, Serialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] struct AdyenSplitData { amount: Option, @@ -1253,13 +1253,15 @@ pub struct DokuBankData { } // Refunds Request and Response #[serde_with::skip_serializing_none] -#[derive(Default, Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct AdyenRefundRequest { merchant_account: Secret, amount: Amount, merchant_refund_reason: Option, reference: String, + store: Option, + splits: Option>, } #[derive(Default, Debug, Clone, Serialize, Deserialize)] @@ -1270,6 +1272,7 @@ pub struct AdyenRefundResponse { payment_psp_reference: String, reference: String, status: String, + splits: Option>, } pub struct AdyenAuthType { @@ -2768,15 +2771,15 @@ impl } // }?; - let (store_id, splits) = item - .router_data - .request - .split_payments - .as_ref() - .and_then(|split_payment_data| { - get_adyen_split_request(split_payment_data, item.router_data.request.currency) - }) - .unwrap_or((None, None)); + let (store, splits) = match item + .router_data + .request + .split_payments + .as_ref() + { + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_payment)) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + _ => (None, None), + }; Ok(AdyenPaymentRequest { amount, @@ -2805,7 +2808,7 @@ impl shopper_ip: item.router_data.request.get_ip_address_as_optional(), metadata: item.router_data.request.metadata.clone().map(Into::into), merchant_order_reference: item.router_data.request.merchant_order_reference_id.clone(), - store_id, + store, splits, }) } @@ -2843,15 +2846,15 @@ impl let payment_method = AdyenPaymentMethod::try_from((card_data, card_holder_name))?; let shopper_email = item.router_data.get_optional_billing_email(); let shopper_name = get_shopper_name(item.router_data.get_optional_billing()); - let (store_id, splits) = item - .router_data - .request - .split_payments - .as_ref() - .and_then(|split_payment_data| { - get_adyen_split_request(split_payment_data, item.router_data.request.currency) - }) - .unwrap_or((None, None)); + let (store, splits) = match item + .router_data + .request + .split_payments + .as_ref() + { + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_payment)) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + _ => (None, None), + }; Ok(AdyenPaymentRequest { amount, @@ -2880,7 +2883,7 @@ impl shopper_ip: item.router_data.request.get_ip_address_as_optional(), metadata: item.router_data.request.metadata.clone().map(Into::into), merchant_order_reference: item.router_data.request.merchant_order_reference_id.clone(), - store_id, + store, splits, }) } @@ -2911,15 +2914,15 @@ impl let return_url = item.router_data.request.get_return_url()?; let payment_method = AdyenPaymentMethod::try_from((bank_debit_data, item.router_data))?; let country_code = get_country_code(item.router_data.get_optional_billing()); - let (store_id, splits) = item - .router_data - .request - .split_payments - .as_ref() - .and_then(|split_payment_data| { - get_adyen_split_request(split_payment_data, item.router_data.request.currency) - }) - .unwrap_or((None, None)); + let (store, splits) = match item + .router_data + .request + .split_payments + .as_ref() + { + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_payment)) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + _ => (None, None), + }; let request = AdyenPaymentRequest { amount, merchant_account: auth_type.merchant_account, @@ -2947,7 +2950,7 @@ impl shopper_ip: item.router_data.request.get_ip_address_as_optional(), metadata: item.router_data.request.metadata.clone().map(Into::into), merchant_order_reference: item.router_data.request.merchant_order_reference_id.clone(), - store_id, + store, splits, }; Ok(request) @@ -2981,15 +2984,15 @@ impl let billing_address = get_address_info(item.router_data.get_optional_billing()).and_then(Result::ok); let shopper_name = get_shopper_name(item.router_data.get_optional_billing()); - let (store_id, splits) = item - .router_data - .request - .split_payments - .as_ref() - .and_then(|split_payment_data| { - get_adyen_split_request(split_payment_data, item.router_data.request.currency) - }) - .unwrap_or((None, None)); + let (store, splits) = match item + .router_data + .request + .split_payments + .as_ref() + { + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_payment)) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + _ => (None, None), + }; let request = AdyenPaymentRequest { amount, @@ -3018,7 +3021,7 @@ impl shopper_ip: item.router_data.request.get_ip_address_as_optional(), metadata: item.router_data.request.metadata.clone().map(Into::into), merchant_order_reference: item.router_data.request.merchant_order_reference_id.clone(), - store_id, + store, splits, }; Ok(request) @@ -3045,15 +3048,15 @@ impl let shopper_interaction = AdyenShopperInteraction::from(item.router_data); let payment_method = AdyenPaymentMethod::try_from((bank_transfer_data, item.router_data))?; let return_url = item.router_data.request.get_return_url()?; - let (store_id, splits) = item - .router_data - .request - .split_payments - .as_ref() - .and_then(|split_payment_data| { - get_adyen_split_request(split_payment_data, item.router_data.request.currency) - }) - .unwrap_or((None, None)); + let (store, splits) = match item + .router_data + .request + .split_payments + .as_ref() + { + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_payment)) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + _ => (None, None), + }; let request = AdyenPaymentRequest { amount, merchant_account: auth_type.merchant_account, @@ -3081,7 +3084,7 @@ impl shopper_ip: item.router_data.request.get_ip_address_as_optional(), metadata: item.router_data.request.metadata.clone().map(Into::into), merchant_order_reference: item.router_data.request.merchant_order_reference_id.clone(), - store_id, + store, splits, }; Ok(request) @@ -3108,15 +3111,15 @@ impl let shopper_interaction = AdyenShopperInteraction::from(item.router_data); let return_url = item.router_data.request.get_router_return_url()?; let payment_method = AdyenPaymentMethod::try_from(gift_card_data)?; - let (store_id, splits) = item - .router_data - .request - .split_payments - .as_ref() - .and_then(|split_payment_data| { - get_adyen_split_request(split_payment_data, item.router_data.request.currency) - }) - .unwrap_or((None, None)); + let (store, splits) = match item + .router_data + .request + .split_payments + .as_ref() + { + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_payment)) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + _ => (None, None), + }; let request = AdyenPaymentRequest { amount, @@ -3145,7 +3148,7 @@ impl shopper_ip: item.router_data.request.get_ip_address_as_optional(), metadata: item.router_data.request.metadata.clone().map(Into::into), merchant_order_reference: item.router_data.request.merchant_order_reference_id.clone(), - store_id, + store, splits, }; Ok(request) @@ -3183,15 +3186,15 @@ impl let line_items = Some(get_line_items(item)); let billing_address = get_address_info(item.router_data.get_optional_billing()).and_then(Result::ok); - let (store_id, splits) = item + let (store, splits) = match item .router_data .request .split_payments .as_ref() - .and_then(|split_payment_data| { - get_adyen_split_request(split_payment_data, item.router_data.request.currency) - }) - .unwrap_or((None, None)); + { + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_payment)) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + _ => (None, None), + }; Ok(AdyenPaymentRequest { amount, @@ -3220,7 +3223,7 @@ impl shopper_ip: item.router_data.request.get_ip_address_as_optional(), metadata: item.router_data.request.metadata.clone().map(Into::into), merchant_order_reference: item.router_data.request.merchant_order_reference_id.clone(), - store_id, + store, splits, }) } @@ -3312,15 +3315,15 @@ impl } else { None }; - let (store_id, splits) = item - .router_data - .request - .split_payments - .as_ref() - .and_then(|split_payment_data| { - get_adyen_split_request(split_payment_data, item.router_data.request.currency) - }) - .unwrap_or((None, None)); + let (store, splits) = match item + .router_data + .request + .split_payments + .as_ref() + { + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_payment)) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + _ => (None, None), + }; Ok(AdyenPaymentRequest { amount, merchant_account: auth_type.merchant_account, @@ -3348,7 +3351,7 @@ impl shopper_ip: item.router_data.request.get_ip_address_as_optional(), metadata: item.router_data.request.metadata.clone().map(Into::into), merchant_order_reference: item.router_data.request.merchant_order_reference_id.clone(), - store_id, + store, splits, }) } @@ -3399,15 +3402,15 @@ impl &billing_address, &delivery_address, ))?; - let (store_id, splits) = item - .router_data - .request - .split_payments - .as_ref() - .and_then(|split_payment_data| { - get_adyen_split_request(split_payment_data, item.router_data.request.currency) - }) - .unwrap_or((None, None)); + let (store, splits) = match item + .router_data + .request + .split_payments + .as_ref() + { + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_payment)) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + _ => (None, None), + }; Ok(AdyenPaymentRequest { amount, @@ -3436,7 +3439,7 @@ impl shopper_ip: item.router_data.request.get_ip_address_as_optional(), metadata: item.router_data.request.metadata.clone().map(Into::into), merchant_order_reference: item.router_data.request.merchant_order_reference_id.clone(), - store_id, + store, splits, }) } @@ -3471,15 +3474,15 @@ impl })? .number .to_owned(); - let (store_id, splits) = item - .router_data - .request - .split_payments - .as_ref() - .and_then(|split_payment_data| { - get_adyen_split_request(split_payment_data, item.router_data.request.currency) - }) - .unwrap_or((None, None)); + let (store, splits) = match item + .router_data + .request + .split_payments + .as_ref() + { + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_payment)) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + _ => (None, None), + }; Ok(AdyenPaymentRequest { amount, @@ -3508,7 +3511,7 @@ impl shopper_ip: item.router_data.request.get_ip_address_as_optional(), metadata: item.router_data.request.metadata.clone().map(Into::into), merchant_order_reference: item.router_data.request.merchant_order_reference_id.clone(), - store_id, + store, splits, }) } @@ -3526,12 +3529,10 @@ impl TryFrom<&types::PaymentsCancelRouterData> for AdyenCancelRequest { } fn get_adyen_split_request( - item: &common_types::payments::SplitPaymentsRequest, + split_request: &common_types::domain::AdyenSplitData, currency: common_enums::enums::Currency, -) -> Option<(Option, Option>)> { - match item { - common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(split_payment_data) => { - let splits: Vec = split_payment_data +) -> (Option, Option>) { + let splits = split_request .split_items .iter() .map(|split_item| { @@ -3545,11 +3546,7 @@ fn get_adyen_split_request( } }) .collect(); - - Some((split_payment_data.store_id.clone(), Some(splits))) - } - _ => None, - } + (split_request.store.clone(), Some(splits)) } impl TryFrom> @@ -3622,6 +3619,7 @@ pub fn get_adyen_response( is_capture_manual: bool, status_code: u16, pmt: Option, + split_request: Option, ) -> errors::CustomResult< ( storage_enums::AttemptStatus, @@ -3668,6 +3666,14 @@ pub fn get_adyen_response( .map(|network_tx_id| network_tx_id.expose()) }); + let charges = + match split_request { + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_data)) => { + Some(common_types::payments::ConnectorChargeResponseData::AdyenSplitPayment(adyen_split_data)) + }, + _ => None + }; + let payments_response_data = types::PaymentsResponseData::TransactionResponse { resource_id: types::ResponseId::ConnectorTransactionId(response.psp_reference), redirection_data: Box::new(None), @@ -3676,7 +3682,7 @@ pub fn get_adyen_response( network_txn_id, connector_response_reference_id: Some(response.merchant_reference), incremental_authorization_allowed: None, - charges: None, + charges, }; Ok((status, error, payments_response_data)) } @@ -3754,6 +3760,7 @@ pub fn get_redirection_response( is_manual_capture: bool, status_code: u16, pmt: Option, + split_request: Option, ) -> errors::CustomResult< ( storage_enums::AttemptStatus, @@ -3805,6 +3812,14 @@ pub fn get_redirection_response( let connector_metadata = get_wait_screen_metadata(&response)?; + let charges = + match split_request { + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_data)) => { + Some(common_types::payments::ConnectorChargeResponseData::AdyenSplitPayment(adyen_split_data)) + }, + _ => None + }; + let payments_response_data = types::PaymentsResponseData::TransactionResponse { resource_id: match response.psp_reference.as_ref() { Some(psp) => types::ResponseId::ConnectorTransactionId(psp.to_string()), @@ -3819,7 +3834,7 @@ pub fn get_redirection_response( .clone() .or(response.psp_reference), incremental_authorization_allowed: None, - charges: None, + charges, }; Ok((status, error, payments_response_data)) } @@ -3829,6 +3844,7 @@ pub fn get_present_to_shopper_response( is_manual_capture: bool, status_code: u16, pmt: Option, + split_request: Option, ) -> errors::CustomResult< ( storage_enums::AttemptStatus, @@ -3864,6 +3880,14 @@ pub fn get_present_to_shopper_response( None }; + let charges = + match split_request { + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_data)) => { + Some(common_types::payments::ConnectorChargeResponseData::AdyenSplitPayment(adyen_split_data)) + }, + _ => None + }; + let connector_metadata = get_present_to_shopper_metadata(&response)?; // We don't get connector transaction id for redirections in Adyen. let payments_response_data = types::PaymentsResponseData::TransactionResponse { @@ -3880,16 +3904,18 @@ pub fn get_present_to_shopper_response( .clone() .or(response.psp_reference), incremental_authorization_allowed: None, - charges: None, + charges, }; Ok((status, error, payments_response_data)) } + pub fn get_qr_code_response( response: QrCodeResponseResponse, is_manual_capture: bool, status_code: u16, pmt: Option, + split_request: Option, ) -> errors::CustomResult< ( storage_enums::AttemptStatus, @@ -3925,6 +3951,14 @@ pub fn get_qr_code_response( None }; + let charges = + match split_request { + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_data)) => { + Some(common_types::payments::ConnectorChargeResponseData::AdyenSplitPayment(adyen_split_data)) + }, + _ => None + }; + let connector_metadata = get_qr_metadata(&response)?; let payments_response_data = types::PaymentsResponseData::TransactionResponse { resource_id: match response.psp_reference.as_ref() { @@ -3940,7 +3974,7 @@ pub fn get_qr_code_response( .clone() .or(response.psp_reference), incremental_authorization_allowed: None, - charges: None, + charges, }; Ok((status, error, payments_response_data)) } @@ -4239,6 +4273,7 @@ impl bool, Option, )> for types::RouterData + where Req : utils::SplitPaymentData, { type Error = Error; fn foreign_try_from( @@ -4250,18 +4285,19 @@ impl ), ) -> Result { let is_manual_capture = utils::is_manual_capture(capture_method); + let split_request = item.data.request.get_split_payment_data(); let (status, error, payment_response_data) = match item.response { AdyenPaymentResponse::Response(response) => { - get_adyen_response(*response, is_manual_capture, item.http_code, pmt)? + get_adyen_response(*response, is_manual_capture, item.http_code, pmt, split_request)? } AdyenPaymentResponse::PresentToShopper(response) => { - get_present_to_shopper_response(*response, is_manual_capture, item.http_code, pmt)? + get_present_to_shopper_response(*response, is_manual_capture, item.http_code, pmt, split_request)? } AdyenPaymentResponse::QrCodeResponse(response) => { - get_qr_code_response(*response, is_manual_capture, item.http_code, pmt)? + get_qr_code_response(*response, is_manual_capture, item.http_code, pmt, split_request)? } AdyenPaymentResponse::RedirectionResponse(response) => { - get_redirection_response(*response, is_manual_capture, item.http_code, pmt)? + get_redirection_response(*response, is_manual_capture, item.http_code, pmt, split_request)? } AdyenPaymentResponse::RedirectionErrorResponse(response) => { get_redirection_error_response(*response, is_manual_capture, item.http_code, pmt)? @@ -4396,6 +4432,16 @@ impl TryFrom<&AdyenRouterData<&types::RefundsRouterData>> for AdyenRefundR type Error = Error; fn try_from(item: &AdyenRouterData<&types::RefundsRouterData>) -> Result { let auth_type = AdyenAuthType::try_from(&item.router_data.connector_auth_type)?; + let (store, splits) = match item + .router_data + .request + .split_refunds + .as_ref() + { + Some(hyperswitch_domain_models::router_request_types::SplitRefundsRequest::AdyenSplitRefund(adyen_split_data)) => get_adyen_split_request(&adyen_split_data, item.router_data.request.currency), + _ => (None, None), + }; + Ok(Self { merchant_account: auth_type.merchant_account, amount: Amount { @@ -4404,6 +4450,8 @@ impl TryFrom<&AdyenRouterData<&types::RefundsRouterData>> for AdyenRefundR }, merchant_refund_reason: item.router_data.request.reason.clone(), reference: item.router_data.request.refund_id.clone(), + store, + splits, }) } } @@ -5613,15 +5661,15 @@ impl .unwrap_or_default(), eci: Some("02".to_string()), }; - let (store_id, splits) = item - .router_data - .request - .split_payments - .as_ref() - .and_then(|split_payment_data| { - get_adyen_split_request(split_payment_data, item.router_data.request.currency) - }) - .unwrap_or((None, None)); + let (store, splits) = match item + .router_data + .request + .split_payments + .as_ref() + { + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_payment)) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + _ => (None, None), + }; Ok(AdyenPaymentRequest { amount, @@ -5650,7 +5698,7 @@ impl metadata: item.router_data.request.metadata.clone().map(Into::into), merchant_order_reference: item.router_data.request.merchant_order_reference_id.clone(), mpi_data: Some(mpi_data), - store_id, + store, splits, }) } diff --git a/crates/router/src/connector/utils.rs b/crates/router/src/connector/utils.rs index a72a1ec18bde..087148abf1e7 100644 --- a/crates/router/src/connector/utils.rs +++ b/crates/router/src/connector/utils.rs @@ -24,8 +24,7 @@ use hyperswitch_domain_models::{ mandates, payments::payment_attempt::PaymentAttempt, router_request_types::{ - AuthoriseIntegrityObject, CaptureIntegrityObject, RefundIntegrityObject, - SyncIntegrityObject, + AuthoriseIntegrityObject, CaptureIntegrityObject, RefundIntegrityObject, SyncIntegrityObject }, }; use masking::{Deserialize, ExposeInterface, Secret}; @@ -787,6 +786,12 @@ impl SplitPaymentData for PaymentsCancelData { } } +impl SplitPaymentData for types::SetupMandateRequestData { + fn get_split_payment_data(&self) -> Option { + None + } +} + pub trait RevokeMandateRequestData { fn get_connector_mandate_id(&self) -> Result; } diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index 19aba7e09e21..5feec3499f1b 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -6333,7 +6333,7 @@ pub fn validate_platform_request_for_marketplace( "split_payments.adyen_split_payment.split_items.account", }); } - if adyen_split_payment.store_id.is_some() { + if adyen_split_payment.store.is_some() { return Err(errors::ApiErrorResponse::PreconditionFailed { message: "Topup split payment is not available via Adyen Platform" .to_string(), diff --git a/crates/router/src/core/refunds/transformers.rs b/crates/router/src/core/refunds/transformers.rs index 7235068c947d..bc7041d5b39a 100644 --- a/crates/router/src/core/refunds/transformers.rs +++ b/crates/router/src/core/refunds/transformers.rs @@ -3,45 +3,4 @@ pub struct SplitRefundInput { pub payment_charges: Option, pub split_payment_request: Option, pub charge_id: Option, -} - -// impl TryFrom for router_request_types::SplitRefundsRequest { -// type Error = Report; - -// fn try_from(value: SplitRefundInput) -> Result { -// let SplitRefundInput { -// refund_request, -// payment_charges, -// charge_id, -// } = value; - -// match refund_request { -// common_types::refunds::SplitRefund::StripeSplitRefund(stripe_refund) => { -// if let Some((split_charge_id, options)) = -// validator::validate_stripe_charge_refund( -// &charge_id, -// &Some(refund_request), -// None, -// &Some(payment_charges), -// )? { - -// Ok(Self::StripeSplitRefund( -// router_request_types::StripeSplitRefund { -// charge_id: split_charge_id.clone(), -// transfer_account_id: stripe_refund.transfer_account_id.clone(), -// charge_type: stripe_refund.charge_type.clone(), -// options, -// }, -// )) -// } else { -// None -// } -// } -// common_types::refunds::SplitRefund::AdyenSplitRefund(adyen_refund) => { -// Ok(Self::AdyenSplitRefund( -// adyen_refund, -// )) -// } -// } -// } -// } +} \ No newline at end of file diff --git a/crates/router/src/core/refunds/validator.rs b/crates/router/src/core/refunds/validator.rs index 1ea288bba413..20acb0743a08 100644 --- a/crates/router/src/core/refunds/validator.rs +++ b/crates/router/src/core/refunds/validator.rs @@ -191,9 +191,9 @@ pub fn validate_adyen_charge_refund( adyen_split_payment_response: &common_types::domain::AdyenSplitData, adyen_split_refund_request: &common_types::domain::AdyenSplitData, ) -> RouterResult<()> { - if adyen_split_refund_request.store_id != adyen_split_payment_response.store_id { + if adyen_split_refund_request.store != adyen_split_payment_response.store { return Err(report!(errors::ApiErrorResponse::InvalidDataValue { - field_name: "store_id", + field_name: "store", })); } From 4facdbcdbd7312e5d3edb468753b14db0fc8928d Mon Sep 17 00:00:00 2001 From: AkshayaFoiger Date: Tue, 21 Jan 2025 14:39:03 +0530 Subject: [PATCH 15/21] refactor(router): populate split response from connector --- crates/common_enums/src/enums.rs | 4 +- .../src/connector/adyen/transformers.rs | 93 +++++++++++-------- crates/router/src/core/payments/helpers.rs | 4 +- 3 files changed, 59 insertions(+), 42 deletions(-) diff --git a/crates/common_enums/src/enums.rs b/crates/common_enums/src/enums.rs index e453e81208e9..0c62a58e86aa 100644 --- a/crates/common_enums/src/enums.rs +++ b/crates/common_enums/src/enums.rs @@ -3625,8 +3625,8 @@ pub enum FeatureStatus { strum::EnumString, ToSchema, )] -#[strum(serialize_all = "camelCase")] -#[serde(rename_all = "camelCase")] +#[strum(serialize_all = "PascalCase")] +#[serde(rename_all = "PascalCase")] pub enum AdyenSplitType { /// Books split amount to the specified account. BalanceAccount, diff --git a/crates/router/src/connector/adyen/transformers.rs b/crates/router/src/connector/adyen/transformers.rs index eab6e0550e97..467ca76e7175 100644 --- a/crates/router/src/connector/adyen/transformers.rs +++ b/crates/router/src/connector/adyen/transformers.rs @@ -378,6 +378,8 @@ pub struct Response { refusal_reason: Option, refusal_reason_code: Option, additional_data: Option, + splits: Option>, + store: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -424,6 +426,8 @@ pub struct RedirectionResponse { refusal_reason_code: Option, psp_reference: Option, merchant_reference: Option, + store: Option, + splits: Option>, } #[derive(Debug, Clone, Deserialize, Serialize)] @@ -435,6 +439,8 @@ pub struct PresentToShopperResponse { refusal_reason: Option, refusal_reason_code: Option, merchant_reference: Option, + store: Option, + splits: Option>, } #[derive(Debug, Clone, Deserialize, Serialize)] @@ -447,6 +453,8 @@ pub struct QrCodeResponseResponse { additional_data: Option, psp_reference: Option, merchant_reference: Option, + store: Option, + splits: Option>, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -1260,8 +1268,8 @@ pub struct AdyenRefundRequest { amount: Amount, merchant_refund_reason: Option, reference: String, - store: Option, splits: Option>, + store: Option, } #[derive(Default, Debug, Clone, Serialize, Deserialize)] @@ -1272,7 +1280,6 @@ pub struct AdyenRefundResponse { payment_psp_reference: String, reference: String, status: String, - splits: Option>, } pub struct AdyenAuthType { @@ -3619,7 +3626,6 @@ pub fn get_adyen_response( is_capture_manual: bool, status_code: u16, pmt: Option, - split_request: Option, ) -> errors::CustomResult< ( storage_enums::AttemptStatus, @@ -3666,13 +3672,10 @@ pub fn get_adyen_response( .map(|network_tx_id| network_tx_id.expose()) }); - let charges = - match split_request { - Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_data)) => { - Some(common_types::payments::ConnectorChargeResponseData::AdyenSplitPayment(adyen_split_data)) - }, - _ => None - }; + let charges = match &response.splits { + Some(split_items) => Some(construct_charge_response(response.store, split_items)), + None => None, + }; let payments_response_data = types::PaymentsResponseData::TransactionResponse { resource_id: types::ResponseId::ConnectorTransactionId(response.psp_reference), @@ -3760,7 +3763,6 @@ pub fn get_redirection_response( is_manual_capture: bool, status_code: u16, pmt: Option, - split_request: Option, ) -> errors::CustomResult< ( storage_enums::AttemptStatus, @@ -3812,12 +3814,9 @@ pub fn get_redirection_response( let connector_metadata = get_wait_screen_metadata(&response)?; - let charges = - match split_request { - Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_data)) => { - Some(common_types::payments::ConnectorChargeResponseData::AdyenSplitPayment(adyen_split_data)) - }, - _ => None + let charges = match &response.splits { + Some(split_items) => Some(construct_charge_response(response.store, split_items)), + None => None, }; let payments_response_data = types::PaymentsResponseData::TransactionResponse { @@ -3844,7 +3843,6 @@ pub fn get_present_to_shopper_response( is_manual_capture: bool, status_code: u16, pmt: Option, - split_request: Option, ) -> errors::CustomResult< ( storage_enums::AttemptStatus, @@ -3880,12 +3878,9 @@ pub fn get_present_to_shopper_response( None }; - let charges = - match split_request { - Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_data)) => { - Some(common_types::payments::ConnectorChargeResponseData::AdyenSplitPayment(adyen_split_data)) - }, - _ => None + let charges = match &response.splits { + Some(split_items) => Some(construct_charge_response(response.store.clone(), split_items)), + None => None, }; let connector_metadata = get_present_to_shopper_metadata(&response)?; @@ -3915,7 +3910,6 @@ pub fn get_qr_code_response( is_manual_capture: bool, status_code: u16, pmt: Option, - split_request: Option, ) -> errors::CustomResult< ( storage_enums::AttemptStatus, @@ -3951,12 +3945,9 @@ pub fn get_qr_code_response( None }; - let charges = - match split_request { - Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_data)) => { - Some(common_types::payments::ConnectorChargeResponseData::AdyenSplitPayment(adyen_split_data)) - }, - _ => None + let charges = match &response.splits { + Some(split_items) => Some(construct_charge_response(response.store.clone(), split_items)), + None => None, }; let connector_metadata = get_qr_metadata(&response)?; @@ -4273,7 +4264,6 @@ impl bool, Option, )> for types::RouterData - where Req : utils::SplitPaymentData, { type Error = Error; fn foreign_try_from( @@ -4285,19 +4275,18 @@ impl ), ) -> Result { let is_manual_capture = utils::is_manual_capture(capture_method); - let split_request = item.data.request.get_split_payment_data(); let (status, error, payment_response_data) = match item.response { AdyenPaymentResponse::Response(response) => { - get_adyen_response(*response, is_manual_capture, item.http_code, pmt, split_request)? + get_adyen_response(*response, is_manual_capture, item.http_code, pmt)? } AdyenPaymentResponse::PresentToShopper(response) => { - get_present_to_shopper_response(*response, is_manual_capture, item.http_code, pmt, split_request)? + get_present_to_shopper_response(*response, is_manual_capture, item.http_code, pmt)? } AdyenPaymentResponse::QrCodeResponse(response) => { - get_qr_code_response(*response, is_manual_capture, item.http_code, pmt, split_request)? + get_qr_code_response(*response, is_manual_capture, item.http_code, pmt)? } AdyenPaymentResponse::RedirectionResponse(response) => { - get_redirection_response(*response, is_manual_capture, item.http_code, pmt, split_request)? + get_redirection_response(*response, is_manual_capture, item.http_code, pmt)? } AdyenPaymentResponse::RedirectionErrorResponse(response) => { get_redirection_error_response(*response, is_manual_capture, item.http_code, pmt)? @@ -4359,6 +4348,8 @@ pub struct AdyenCaptureResponse { status: String, amount: Amount, merchant_reference: Option, + store: Option, + splits: Option>, } impl TryFrom> @@ -4373,6 +4364,11 @@ impl TryFrom> } else { item.response.payment_psp_reference }; + let charges = match &item.response.splits { + Some(split_items) => Some(construct_charge_response(item.response.store, split_items)), + None => None, + }; + Ok(Self { // From the docs, the only value returned is "received", outcome of refund is available // through refund notification webhook @@ -4386,7 +4382,7 @@ impl TryFrom> network_txn_id: None, connector_response_reference_id: Some(item.response.reference), incremental_authorization_allowed: None, - charges: None, + charges, }), amount_captured: Some(0), ..item.data @@ -4394,6 +4390,27 @@ impl TryFrom> } } + +fn construct_charge_response(store: Option, split_item: &Vec) -> common_types::payments::ConnectorChargeResponseData { + let splits: Vec = split_item + .iter() + .map(|split_item| common_types::domain::AdyenSplitItem { + amount: split_item.amount.as_ref().map(|amount| amount.value.clone()), + reference: split_item.reference.clone(), + split_type: split_item.split_type.clone(), + account: split_item.account.clone(), + description: split_item.description.clone(), + }) + .collect(); + + common_types::payments::ConnectorChargeResponseData::AdyenSplitPayment( + common_types::domain::AdyenSplitData { + store, + split_items: splits, + }, + ) +} + /* // This is a repeated code block from Stripe inegration. Can we avoid the repetition in every integration #[derive(Debug, Serialize, Deserialize)] diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index 5feec3499f1b..d3918d91d556 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -6283,7 +6283,7 @@ pub fn validate_platform_request_for_marketplace( api::Amount::Zero => { if total_split_amount != 0 { return Err(errors::ApiErrorResponse::InvalidDataValue { - field_name: "split_payments.adyen_split_payment.amount", + field_name: "Sum of split amounts should be equal to the total amount", }); } } @@ -6293,7 +6293,7 @@ pub fn validate_platform_request_for_marketplace( && i64_amount != total_split_amount { return Err(errors::ApiErrorResponse::PreconditionFailed { - message: "split_payments.adyen_split_payment.amount".to_string(), + message: "Sum of split amounts should be equal to the total amount".to_string(), }); } } From c25f427c4ea453fe28dc394cb1ed48d0bfbf24e3 Mon Sep 17 00:00:00 2001 From: "hyperswitch-bot[bot]" <148525504+hyperswitch-bot[bot]@users.noreply.github.com> Date: Tue, 21 Jan 2025 09:26:35 +0000 Subject: [PATCH 16/21] chore: run formatter --- .../src/connector/adyen/transformers.rs | 211 ++++++++---------- crates/router/src/connector/utils.rs | 3 +- crates/router/src/core/payments/helpers.rs | 3 +- .../router/src/core/payments/transformers.rs | 1 - .../router/src/core/refunds/transformers.rs | 2 +- 5 files changed, 99 insertions(+), 121 deletions(-) diff --git a/crates/router/src/connector/adyen/transformers.rs b/crates/router/src/connector/adyen/transformers.rs index 34585f6e5db6..99b278fa85a5 100644 --- a/crates/router/src/connector/adyen/transformers.rs +++ b/crates/router/src/connector/adyen/transformers.rs @@ -2778,13 +2778,10 @@ impl } // }?; - let (store, splits) = match item - .router_data - .request - .split_payments - .as_ref() - { - Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_payment)) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + let (store, splits) = match item.router_data.request.split_payments.as_ref() { + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment( + adyen_split_payment, + )) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), _ => (None, None), }; @@ -2853,13 +2850,10 @@ impl let payment_method = AdyenPaymentMethod::try_from((card_data, card_holder_name))?; let shopper_email = item.router_data.get_optional_billing_email(); let shopper_name = get_shopper_name(item.router_data.get_optional_billing()); - let (store, splits) = match item - .router_data - .request - .split_payments - .as_ref() - { - Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_payment)) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + let (store, splits) = match item.router_data.request.split_payments.as_ref() { + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment( + adyen_split_payment, + )) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), _ => (None, None), }; @@ -2921,13 +2915,10 @@ impl let return_url = item.router_data.request.get_router_return_url()?; let payment_method = AdyenPaymentMethod::try_from((bank_debit_data, item.router_data))?; let country_code = get_country_code(item.router_data.get_optional_billing()); - let (store, splits) = match item - .router_data - .request - .split_payments - .as_ref() - { - Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_payment)) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + let (store, splits) = match item.router_data.request.split_payments.as_ref() { + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment( + adyen_split_payment, + )) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), _ => (None, None), }; let request = AdyenPaymentRequest { @@ -2991,13 +2982,10 @@ impl let billing_address = get_address_info(item.router_data.get_optional_billing()).and_then(Result::ok); let shopper_name = get_shopper_name(item.router_data.get_optional_billing()); - let (store, splits) = match item - .router_data - .request - .split_payments - .as_ref() - { - Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_payment)) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + let (store, splits) = match item.router_data.request.split_payments.as_ref() { + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment( + adyen_split_payment, + )) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), _ => (None, None), }; @@ -3055,13 +3043,10 @@ impl let shopper_interaction = AdyenShopperInteraction::from(item.router_data); let payment_method = AdyenPaymentMethod::try_from((bank_transfer_data, item.router_data))?; let return_url = item.router_data.request.get_router_return_url()?; - let (store, splits) = match item - .router_data - .request - .split_payments - .as_ref() - { - Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_payment)) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + let (store, splits) = match item.router_data.request.split_payments.as_ref() { + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment( + adyen_split_payment, + )) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), _ => (None, None), }; let request = AdyenPaymentRequest { @@ -3118,13 +3103,10 @@ impl let shopper_interaction = AdyenShopperInteraction::from(item.router_data); let return_url = item.router_data.request.get_router_return_url()?; let payment_method = AdyenPaymentMethod::try_from(gift_card_data)?; - let (store, splits) = match item - .router_data - .request - .split_payments - .as_ref() - { - Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_payment)) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + let (store, splits) = match item.router_data.request.split_payments.as_ref() { + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment( + adyen_split_payment, + )) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), _ => (None, None), }; @@ -3193,15 +3175,12 @@ impl let line_items = Some(get_line_items(item)); let billing_address = get_address_info(item.router_data.get_optional_billing()).and_then(Result::ok); - let (store, splits) = match item - .router_data - .request - .split_payments - .as_ref() - { - Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_payment)) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), - _ => (None, None), - }; + let (store, splits) = match item.router_data.request.split_payments.as_ref() { + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment( + adyen_split_payment, + )) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + _ => (None, None), + }; Ok(AdyenPaymentRequest { amount, @@ -3322,13 +3301,10 @@ impl } else { None }; - let (store, splits) = match item - .router_data - .request - .split_payments - .as_ref() - { - Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_payment)) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + let (store, splits) = match item.router_data.request.split_payments.as_ref() { + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment( + adyen_split_payment, + )) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), _ => (None, None), }; Ok(AdyenPaymentRequest { @@ -3409,13 +3385,10 @@ impl &billing_address, &delivery_address, ))?; - let (store, splits) = match item - .router_data - .request - .split_payments - .as_ref() - { - Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_payment)) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + let (store, splits) = match item.router_data.request.split_payments.as_ref() { + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment( + adyen_split_payment, + )) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), _ => (None, None), }; @@ -3481,13 +3454,10 @@ impl })? .number .to_owned(); - let (store, splits) = match item - .router_data - .request - .split_payments - .as_ref() - { - Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_payment)) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + let (store, splits) = match item.router_data.request.split_payments.as_ref() { + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment( + adyen_split_payment, + )) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), _ => (None, None), }; @@ -3540,20 +3510,20 @@ fn get_adyen_split_request( currency: common_enums::enums::Currency, ) -> (Option, Option>) { let splits = split_request - .split_items - .iter() - .map(|split_item| { - let amount = split_item.amount.map(|value| Amount { currency, value }); - AdyenSplitData { - amount, - reference: split_item.reference.clone(), - split_type: split_item.split_type.clone(), - account: split_item.account.clone(), - description: split_item.description.clone(), - } - }) - .collect(); - (split_request.store.clone(), Some(splits)) + .split_items + .iter() + .map(|split_item| { + let amount = split_item.amount.map(|value| Amount { currency, value }); + AdyenSplitData { + amount, + reference: split_item.reference.clone(), + split_type: split_item.split_type.clone(), + account: split_item.account.clone(), + description: split_item.description.clone(), + } + }) + .collect(); + (split_request.store.clone(), Some(splits)) } impl TryFrom> @@ -3879,7 +3849,10 @@ pub fn get_present_to_shopper_response( }; let charges = match &response.splits { - Some(split_items) => Some(construct_charge_response(response.store.clone(), split_items)), + Some(split_items) => Some(construct_charge_response( + response.store.clone(), + split_items, + )), None => None, }; @@ -3904,7 +3877,6 @@ pub fn get_present_to_shopper_response( Ok((status, error, payments_response_data)) } - pub fn get_qr_code_response( response: QrCodeResponseResponse, is_manual_capture: bool, @@ -3946,7 +3918,10 @@ pub fn get_qr_code_response( }; let charges = match &response.splits { - Some(split_items) => Some(construct_charge_response(response.store.clone(), split_items)), + Some(split_items) => Some(construct_charge_response( + response.store.clone(), + split_items, + )), None => None, }; @@ -4368,7 +4343,7 @@ impl TryFrom> Some(split_items) => Some(construct_charge_response(item.response.store, split_items)), None => None, }; - + Ok(Self { // From the docs, the only value returned is "received", outcome of refund is available // through refund notification webhook @@ -4390,27 +4365,32 @@ impl TryFrom> } } +fn construct_charge_response( + store: Option, + split_item: &Vec, +) -> common_types::payments::ConnectorChargeResponseData { + let splits: Vec = split_item + .iter() + .map(|split_item| common_types::domain::AdyenSplitItem { + amount: split_item + .amount + .as_ref() + .map(|amount| amount.value.clone()), + reference: split_item.reference.clone(), + split_type: split_item.split_type.clone(), + account: split_item.account.clone(), + description: split_item.description.clone(), + }) + .collect(); -fn construct_charge_response(store: Option, split_item: &Vec) -> common_types::payments::ConnectorChargeResponseData { - let splits: Vec = split_item - .iter() - .map(|split_item| common_types::domain::AdyenSplitItem { - amount: split_item.amount.as_ref().map(|amount| amount.value.clone()), - reference: split_item.reference.clone(), - split_type: split_item.split_type.clone(), - account: split_item.account.clone(), - description: split_item.description.clone(), - }) - .collect(); - - common_types::payments::ConnectorChargeResponseData::AdyenSplitPayment( - common_types::domain::AdyenSplitData { - store, - split_items: splits, - }, - ) + common_types::payments::ConnectorChargeResponseData::AdyenSplitPayment( + common_types::domain::AdyenSplitData { + store, + split_items: splits, + }, + ) } - + /* // This is a repeated code block from Stripe inegration. Can we avoid the repetition in every integration #[derive(Debug, Serialize, Deserialize)] @@ -4458,7 +4438,7 @@ impl TryFrom<&AdyenRouterData<&types::RefundsRouterData>> for AdyenRefundR Some(hyperswitch_domain_models::router_request_types::SplitRefundsRequest::AdyenSplitRefund(adyen_split_data)) => get_adyen_split_request(&adyen_split_data, item.router_data.request.currency), _ => (None, None), }; - + Ok(Self { merchant_account: auth_type.merchant_account, amount: Amount { @@ -5678,13 +5658,10 @@ impl .unwrap_or_default(), eci: Some("02".to_string()), }; - let (store, splits) = match item - .router_data - .request - .split_payments - .as_ref() - { - Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment(adyen_split_payment)) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + let (store, splits) = match item.router_data.request.split_payments.as_ref() { + Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment( + adyen_split_payment, + )) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), _ => (None, None), }; diff --git a/crates/router/src/connector/utils.rs b/crates/router/src/connector/utils.rs index c0bf365abdfe..a75b5ee854b2 100644 --- a/crates/router/src/connector/utils.rs +++ b/crates/router/src/connector/utils.rs @@ -24,7 +24,8 @@ use hyperswitch_domain_models::{ mandates, payments::payment_attempt::PaymentAttempt, router_request_types::{ - AuthoriseIntegrityObject, CaptureIntegrityObject, RefundIntegrityObject, SyncIntegrityObject + AuthoriseIntegrityObject, CaptureIntegrityObject, RefundIntegrityObject, + SyncIntegrityObject, }, }; use masking::{Deserialize, ExposeInterface, Secret}; diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index a5516bf2c17d..1346e9d96370 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -6296,7 +6296,8 @@ pub fn validate_platform_request_for_marketplace( && i64_amount != total_split_amount { return Err(errors::ApiErrorResponse::PreconditionFailed { - message: "Sum of split amounts should be equal to the total amount".to_string(), + message: "Sum of split amounts should be equal to the total amount" + .to_string(), }); } } diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index 828a5bead168..9d96f0b9c6ab 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -2103,7 +2103,6 @@ where ) }); - let mandate_data = payment_data.get_setup_mandate().map(|d| api::MandateData { customer_acceptance: d .customer_acceptance diff --git a/crates/router/src/core/refunds/transformers.rs b/crates/router/src/core/refunds/transformers.rs index bc7041d5b39a..151c6d202343 100644 --- a/crates/router/src/core/refunds/transformers.rs +++ b/crates/router/src/core/refunds/transformers.rs @@ -3,4 +3,4 @@ pub struct SplitRefundInput { pub payment_charges: Option, pub split_payment_request: Option, pub charge_id: Option, -} \ No newline at end of file +} From 5d7906f7d5399ad3c7964bb9c1708ac1582d1fc8 Mon Sep 17 00:00:00 2001 From: AkshayaFoiger Date: Tue, 21 Jan 2025 15:43:56 +0530 Subject: [PATCH 17/21] chore: fix merge conflict --- .../src/connectors/deutschebank/transformers.rs | 4 ++-- .../src/connectors/xendit/transformers.rs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs b/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs index 571944fd8520..99932f6f51a2 100644 --- a/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs @@ -389,7 +389,7 @@ impl network_txn_id: None, connector_response_reference_id: Some(processed.tx_id.clone()), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }), @@ -421,7 +421,7 @@ impl network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }), ..item.data }), diff --git a/crates/hyperswitch_connectors/src/connectors/xendit/transformers.rs b/crates/hyperswitch_connectors/src/connectors/xendit/transformers.rs index 8ff4b74c076e..7a7789e73ab4 100644 --- a/crates/hyperswitch_connectors/src/connectors/xendit/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/xendit/transformers.rs @@ -320,7 +320,7 @@ impl item.response.reference_id.peek().to_string(), ), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }) }; Ok(Self { @@ -378,7 +378,7 @@ impl item.response.reference_id.peek().to_string(), ), incremental_authorization_allowed: None, - charge_id: None, + charges: None, }) }; Ok(Self { @@ -427,7 +427,7 @@ impl TryFrom> for Payments network_txn_id: None, connector_response_reference_id: None, incremental_authorization_allowed: None, - charge_id: None, + charges: None, }) }; Ok(Self { From 5f6e653c0d591c856c8822ae8cbdf5d60b11d2a2 Mon Sep 17 00:00:00 2001 From: AkshayaFoiger Date: Wed, 22 Jan 2025 13:22:23 +0530 Subject: [PATCH 18/21] chore: generate openapi_spec --- api-reference-v2/openapi_spec.json | 158 +++++++++++++++++++++++------ api-reference/openapi_spec.json | 158 +++++++++++++++++++++++------ crates/openapi/src/openapi.rs | 9 +- crates/openapi/src/openapi_v2.rs | 9 +- 4 files changed, 258 insertions(+), 76 deletions(-) diff --git a/api-reference-v2/openapi_spec.json b/api-reference-v2/openapi_spec.json index b038b16b333e..bf005ad44c5a 100644 --- a/api-reference-v2/openapi_spec.json +++ b/api-reference-v2/openapi_spec.json @@ -3010,6 +3010,63 @@ }, "additionalProperties": false }, + "AdyenSplitData": { + "type": "object", + "description": "Fee information for Split Payments to be charged on the payment being collected for Adyen", + "required": [ + "split_items" + ], + "properties": { + "store": { + "type": "string", + "description": "The store identifier", + "nullable": true + }, + "split_items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AdyenSplitItem" + }, + "description": "Data for the split items" + } + }, + "additionalProperties": false + }, + "AdyenSplitItem": { + "type": "object", + "description": "Data for the split items", + "required": [ + "amount", + "split_type" + ], + "properties": { + "amount": { + "type": "integer", + "format": "int64", + "description": "The amount of the split item", + "example": 6540 + }, + "split_type": { + "$ref": "#/components/schemas/AdyenSplitType" + }, + "account": { + "type": "string", + "description": "The unique identifier of the account to which the split amount is allocated.", + "nullable": true + }, + "reference": { + "type": "string", + "description": "Unique Identifier for the split item", + "nullable": true + }, + "description": { + "type": "string", + "description": "Description for the part of the payment that will be allocated to the specified account.", + "nullable": true + } + }, + "additionalProperties": false + }, "AirwallexData": { "type": "object", "properties": { @@ -6668,6 +6725,33 @@ "zsl" ] }, + "ConnectorChargeResponseData": { + "oneOf": [ + { + "type": "object", + "required": [ + "StripeSplitPayment" + ], + "properties": { + "StripeSplitPayment": { + "$ref": "#/components/schemas/StripeChargeResponseData" + } + } + }, + { + "type": "object", + "required": [ + "AdyenSplitPayment" + ], + "properties": { + "AdyenSplitPayment": { + "$ref": "#/components/schemas/domain_types.AdyenSplitData" + } + } + } + ], + "description": "Charge Information" + }, "ConnectorFeatureMatrixResponse": { "type": "object", "required": [ @@ -15314,7 +15398,7 @@ "split_payments": { "allOf": [ { - "$ref": "#/components/schemas/ConnectorChargeResponseData" + "$ref": "#/components/schemas/common_types.payments.ConnectorChargeResponseData" } ], "nullable": true @@ -16214,7 +16298,7 @@ "split_payments": { "allOf": [ { - "$ref": "#/components/schemas/ConnectorChargeResponseData" + "$ref": "#/components/schemas/common_types.payments.ConnectorChargeResponseData" } ], "nullable": true @@ -20396,24 +20480,20 @@ "$ref": "#/components/schemas/StripeSplitPaymentRequest" } } - } - ], - "description": "Fee information for Split Payments to be charged on the payment being collected" - }, - "ConnectorChargeResponseData": { - "oneOf": [ + }, { "type": "object", "required": [ - "stripe_split_payment" + "adyen_split_payment" ], "properties": { - "stripe_split_payment": { - "$ref": "#/components/schemas/StripeChargeResponseData" + "adyen_split_payment": { + "$ref": "#/components/schemas/domain_types.AdyenSplitData" } } } - ] + ], + "description": "Fee information for Split Payments to be charged on the payment being collected" }, "SplitRefund": { "oneOf": [ @@ -20427,6 +20507,17 @@ "$ref": "#/components/schemas/StripeSplitRefundRequest" } } + }, + { + "type": "object", + "required": [ + "adyen_split_refund" + ], + "properties": { + "adyen_split_refund": { + "$ref": "#/components/schemas/domain_types.AdyenSplitData" + } + } } ], "description": "Charge specific fields for controlling the revert of funds from either platform or connected account. Check sub-fields for more details." @@ -20501,66 +20592,67 @@ "propertyName": "type" } }, - "StripeChargeType": { - "type": "string", - "enum": [ - "direct", - "destination" - ] - }, - "StripeSplitPaymentRequest": { + "StripeChargeResponseData": { "type": "object", - "description": "Fee information for Split Payments to be charged on the payment being collected for Stripe", + "description": "Fee information to be charged on the payment being collected via Stripe", "required": [ "charge_type", "application_fees", "transfer_account_id" ], "properties": { + "charge_id": { + "type": "string", + "description": "Identifier for charge created for the payment", + "nullable": true + }, "charge_type": { "$ref": "#/components/schemas/PaymentChargeType" }, "application_fees": { "type": "integer", "format": "int64", - "description": "Platform fees to be collected on the payment", + "description": "Platform fees collected on the payment", "example": 6540 }, "transfer_account_id": { "type": "string", - "description": "Identifier for the reseller's account to send the funds to" + "description": "Identifier for the reseller's account where the funds were transferred" } }, "additionalProperties": false }, - "StripeChargeResponseData": { + "StripeChargeType": { + "type": "string", + "enum": [ + "direct", + "destination" + ] + }, + "StripeSplitPaymentRequest": { "type": "object", - "description": "Fee information to be charged on the payment being collected", + "description": "Fee information for Split Payments to be charged on the payment being collected for Stripe", "required": [ "charge_type", "application_fees", "transfer_account_id" ], "properties": { - "charge_id": { - "type": "string", - "description": "Identifier for charge created for the payment", - "nullable": true - }, "charge_type": { "$ref": "#/components/schemas/PaymentChargeType" }, "application_fees": { "type": "integer", "format": "int64", - "description": "Platform fees collected on the payment", + "description": "Platform fees to be collected on the payment", "example": 6540 }, "transfer_account_id": { "type": "string", - "description": "Identifier for the reseller's account where the funds were transferred" + "description": "Identifier for the reseller's account to send the funds to" } - } + }, + "additionalProperties": false }, "StripeSplitRefundRequest": { "type": "object", diff --git a/api-reference/openapi_spec.json b/api-reference/openapi_spec.json index 56a7a0bcd593..288976eb5090 100644 --- a/api-reference/openapi_spec.json +++ b/api-reference/openapi_spec.json @@ -5840,6 +5840,63 @@ }, "additionalProperties": false }, + "AdyenSplitData": { + "type": "object", + "description": "Fee information for Split Payments to be charged on the payment being collected for Adyen", + "required": [ + "split_items" + ], + "properties": { + "store": { + "type": "string", + "description": "The store identifier", + "nullable": true + }, + "split_items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AdyenSplitItem" + }, + "description": "Data for the split items" + } + }, + "additionalProperties": false + }, + "AdyenSplitItem": { + "type": "object", + "description": "Data for the split items", + "required": [ + "amount", + "split_type" + ], + "properties": { + "amount": { + "type": "integer", + "format": "int64", + "description": "The amount of the split item", + "example": 6540 + }, + "split_type": { + "$ref": "#/components/schemas/AdyenSplitType" + }, + "account": { + "type": "string", + "description": "The unique identifier of the account to which the split amount is allocated.", + "nullable": true + }, + "reference": { + "type": "string", + "description": "Unique Identifier for the split item", + "nullable": true + }, + "description": { + "type": "string", + "description": "Description for the part of the payment that will be allocated to the specified account.", + "nullable": true + } + }, + "additionalProperties": false + }, "AirwallexData": { "type": "object", "properties": { @@ -9321,6 +9378,33 @@ "zsl" ] }, + "ConnectorChargeResponseData": { + "oneOf": [ + { + "type": "object", + "required": [ + "StripeSplitPayment" + ], + "properties": { + "StripeSplitPayment": { + "$ref": "#/components/schemas/StripeChargeResponseData" + } + } + }, + { + "type": "object", + "required": [ + "AdyenSplitPayment" + ], + "properties": { + "AdyenSplitPayment": { + "$ref": "#/components/schemas/domain_types.AdyenSplitData" + } + } + } + ], + "description": "Charge Information" + }, "ConnectorFeatureMatrixResponse": { "type": "object", "required": [ @@ -18807,7 +18891,7 @@ "split_payments": { "allOf": [ { - "$ref": "#/components/schemas/ConnectorChargeResponseData" + "$ref": "#/components/schemas/common_types.payments.ConnectorChargeResponseData" } ], "nullable": true @@ -20050,7 +20134,7 @@ "split_payments": { "allOf": [ { - "$ref": "#/components/schemas/ConnectorChargeResponseData" + "$ref": "#/components/schemas/common_types.payments.ConnectorChargeResponseData" } ], "nullable": true @@ -24942,24 +25026,20 @@ "$ref": "#/components/schemas/StripeSplitPaymentRequest" } } - } - ], - "description": "Fee information for Split Payments to be charged on the payment being collected" - }, - "ConnectorChargeResponseData": { - "oneOf": [ + }, { "type": "object", "required": [ - "stripe_split_payment" + "adyen_split_payment" ], "properties": { - "stripe_split_payment": { - "$ref": "#/components/schemas/StripeChargeResponseData" + "adyen_split_payment": { + "$ref": "#/components/schemas/domain_types.AdyenSplitData" } } } - ] + ], + "description": "Fee information for Split Payments to be charged on the payment being collected" }, "SplitRefund": { "oneOf": [ @@ -24973,6 +25053,17 @@ "$ref": "#/components/schemas/StripeSplitRefundRequest" } } + }, + { + "type": "object", + "required": [ + "adyen_split_refund" + ], + "properties": { + "adyen_split_refund": { + "$ref": "#/components/schemas/domain_types.AdyenSplitData" + } + } } ], "description": "Charge specific fields for controlling the revert of funds from either platform or connected account. Check sub-fields for more details." @@ -25047,66 +25138,67 @@ "propertyName": "type" } }, - "StripeChargeType": { - "type": "string", - "enum": [ - "direct", - "destination" - ] - }, - "StripeSplitPaymentRequest": { + "StripeChargeResponseData": { "type": "object", - "description": "Fee information for Split Payments to be charged on the payment being collected for Stripe", + "description": "Fee information to be charged on the payment being collected via Stripe", "required": [ "charge_type", "application_fees", "transfer_account_id" ], "properties": { + "charge_id": { + "type": "string", + "description": "Identifier for charge created for the payment", + "nullable": true + }, "charge_type": { "$ref": "#/components/schemas/PaymentChargeType" }, "application_fees": { "type": "integer", "format": "int64", - "description": "Platform fees to be collected on the payment", + "description": "Platform fees collected on the payment", "example": 6540 }, "transfer_account_id": { "type": "string", - "description": "Identifier for the reseller's account to send the funds to" + "description": "Identifier for the reseller's account where the funds were transferred" } }, "additionalProperties": false }, - "StripeChargeResponseData": { + "StripeChargeType": { + "type": "string", + "enum": [ + "direct", + "destination" + ] + }, + "StripeSplitPaymentRequest": { "type": "object", - "description": "Fee information to be charged on the payment being collected", + "description": "Fee information for Split Payments to be charged on the payment being collected for Stripe", "required": [ "charge_type", "application_fees", "transfer_account_id" ], "properties": { - "charge_id": { - "type": "string", - "description": "Identifier for charge created for the payment", - "nullable": true - }, "charge_type": { "$ref": "#/components/schemas/PaymentChargeType" }, "application_fees": { "type": "integer", "format": "int64", - "description": "Platform fees collected on the payment", + "description": "Platform fees to be collected on the payment", "example": 6540 }, "transfer_account_id": { "type": "string", - "description": "Identifier for the reseller's account where the funds were transferred" + "description": "Identifier for the reseller's account to send the funds to" } - } + }, + "additionalProperties": false }, "StripeSplitRefundRequest": { "type": "object", diff --git a/crates/openapi/src/openapi.rs b/crates/openapi/src/openapi.rs index bcff0131a4ab..c074202806ae 100644 --- a/crates/openapi/src/openapi.rs +++ b/crates/openapi/src/openapi.rs @@ -216,14 +216,13 @@ Never share your secret api keys. Keep them guarded and secure. common_utils::payout_method_utils::VenmoAdditionalData, common_types::payments::SplitPaymentsRequest, common_types::payments::StripeSplitPaymentRequest, - common_types::payments::AdyenSplitData, - common_types::payments::AdyenSplitItem, + common_types::domain::AdyenSplitData, + common_types::domain::AdyenSplitItem, common_utils::types::ChargeRefunds, common_types::refunds::SplitRefund, common_types::refunds::StripeSplitRefundRequest, - api_models::payments::ConnectorChargeResponseData, - api_models::payments::StripeChargeResponseData, - api_models::payments::AdyenChargeResponseData, + common_types::payments::ConnectorChargeResponseData, + common_types::payments::StripeChargeResponseData, api_models::refunds::RefundRequest, api_models::refunds::RefundType, api_models::refunds::RefundResponse, diff --git a/crates/openapi/src/openapi_v2.rs b/crates/openapi/src/openapi_v2.rs index 578afaec4428..7712c8669907 100644 --- a/crates/openapi/src/openapi_v2.rs +++ b/crates/openapi/src/openapi_v2.rs @@ -158,15 +158,14 @@ Never share your secret api keys. Keep them guarded and secure. common_utils::payout_method_utils::VenmoAdditionalData, common_types::payments::SplitPaymentsRequest, common_types::payments::StripeSplitPaymentRequest, - common_types::payments::AdyenSplitData, - common_types::payments::AdyenSplitItem, + common_types::domain::AdyenSplitData, + common_types::domain::AdyenSplitItem, common_types::refunds::StripeSplitRefundRequest, common_utils::types::ChargeRefunds, common_types::payment_methods::PaymentMethodsEnabled, common_types::refunds::SplitRefund, - api_models::payments::ConnectorChargeResponseData, - api_models::payments::StripeChargeResponseData, - api_models::payments::AdyenChargeResponseData, + common_types::payments::ConnectorChargeResponseData, + common_types::payments::StripeChargeResponseData, api_models::refunds::RefundRequest, api_models::refunds::RefundsCreateRequest, api_models::refunds::RefundErrorDetails, From 8103d0e9639d6197399dd46fc6057e5ca660aa82 Mon Sep 17 00:00:00 2001 From: AkshayaFoiger Date: Wed, 22 Jan 2025 13:48:17 +0530 Subject: [PATCH 19/21] chore: fix clippy error --- .../src/connector/adyen/transformers.rs | 28 ++++----- .../src/connector/stripe/transformers.rs | 59 ++++++++++--------- crates/router/src/core/utils.rs | 2 +- 3 files changed, 45 insertions(+), 44 deletions(-) diff --git a/crates/router/src/connector/adyen/transformers.rs b/crates/router/src/connector/adyen/transformers.rs index 99b278fa85a5..f0424f931224 100644 --- a/crates/router/src/connector/adyen/transformers.rs +++ b/crates/router/src/connector/adyen/transformers.rs @@ -2781,7 +2781,7 @@ impl let (store, splits) = match item.router_data.request.split_payments.as_ref() { Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment( adyen_split_payment, - )) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + )) => get_adyen_split_request(adyen_split_payment, item.router_data.request.currency), _ => (None, None), }; @@ -2853,7 +2853,7 @@ impl let (store, splits) = match item.router_data.request.split_payments.as_ref() { Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment( adyen_split_payment, - )) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + )) => get_adyen_split_request(adyen_split_payment, item.router_data.request.currency), _ => (None, None), }; @@ -2918,7 +2918,7 @@ impl let (store, splits) = match item.router_data.request.split_payments.as_ref() { Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment( adyen_split_payment, - )) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + )) => get_adyen_split_request(adyen_split_payment, item.router_data.request.currency), _ => (None, None), }; let request = AdyenPaymentRequest { @@ -2985,7 +2985,7 @@ impl let (store, splits) = match item.router_data.request.split_payments.as_ref() { Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment( adyen_split_payment, - )) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + )) => get_adyen_split_request(adyen_split_payment, item.router_data.request.currency), _ => (None, None), }; @@ -3046,7 +3046,7 @@ impl let (store, splits) = match item.router_data.request.split_payments.as_ref() { Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment( adyen_split_payment, - )) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + )) => get_adyen_split_request(adyen_split_payment, item.router_data.request.currency), _ => (None, None), }; let request = AdyenPaymentRequest { @@ -3106,7 +3106,7 @@ impl let (store, splits) = match item.router_data.request.split_payments.as_ref() { Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment( adyen_split_payment, - )) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + )) => get_adyen_split_request(adyen_split_payment, item.router_data.request.currency), _ => (None, None), }; @@ -3178,7 +3178,7 @@ impl let (store, splits) = match item.router_data.request.split_payments.as_ref() { Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment( adyen_split_payment, - )) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + )) => get_adyen_split_request(adyen_split_payment, item.router_data.request.currency), _ => (None, None), }; @@ -3304,7 +3304,7 @@ impl let (store, splits) = match item.router_data.request.split_payments.as_ref() { Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment( adyen_split_payment, - )) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + )) => get_adyen_split_request(adyen_split_payment, item.router_data.request.currency), _ => (None, None), }; Ok(AdyenPaymentRequest { @@ -3388,7 +3388,7 @@ impl let (store, splits) = match item.router_data.request.split_payments.as_ref() { Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment( adyen_split_payment, - )) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + )) => get_adyen_split_request(adyen_split_payment, item.router_data.request.currency), _ => (None, None), }; @@ -3457,7 +3457,7 @@ impl let (store, splits) = match item.router_data.request.split_payments.as_ref() { Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment( adyen_split_payment, - )) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + )) => get_adyen_split_request(adyen_split_payment, item.router_data.request.currency), _ => (None, None), }; @@ -4367,7 +4367,7 @@ impl TryFrom> fn construct_charge_response( store: Option, - split_item: &Vec, + split_item: &[AdyenSplitData], ) -> common_types::payments::ConnectorChargeResponseData { let splits: Vec = split_item .iter() @@ -4375,7 +4375,7 @@ fn construct_charge_response( amount: split_item .amount .as_ref() - .map(|amount| amount.value.clone()), + .map(|amount| amount.value), reference: split_item.reference.clone(), split_type: split_item.split_type.clone(), account: split_item.account.clone(), @@ -4435,7 +4435,7 @@ impl TryFrom<&AdyenRouterData<&types::RefundsRouterData>> for AdyenRefundR .split_refunds .as_ref() { - Some(hyperswitch_domain_models::router_request_types::SplitRefundsRequest::AdyenSplitRefund(adyen_split_data)) => get_adyen_split_request(&adyen_split_data, item.router_data.request.currency), + Some(hyperswitch_domain_models::router_request_types::SplitRefundsRequest::AdyenSplitRefund(adyen_split_data)) => get_adyen_split_request(adyen_split_data, item.router_data.request.currency), _ => (None, None), }; @@ -5661,7 +5661,7 @@ impl let (store, splits) = match item.router_data.request.split_payments.as_ref() { Some(common_types::payments::SplitPaymentsRequest::AdyenSplitPayment( adyen_split_payment, - )) => get_adyen_split_request(&adyen_split_payment, item.router_data.request.currency), + )) => get_adyen_split_request(adyen_split_payment, item.router_data.request.currency), _ => (None, None), }; diff --git a/crates/router/src/connector/stripe/transformers.rs b/crates/router/src/connector/stripe/transformers.rs index c0c3225d52f3..6c6f864511a8 100644 --- a/crates/router/src/connector/stripe/transformers.rs +++ b/crates/router/src/connector/stripe/transformers.rs @@ -4163,6 +4163,35 @@ pub(super) fn transform_headers_for_connect_platform( } } +pub fn construct_charge_response( + charge_id: String, + request: &T, +) -> Option +where + T: connector_util::SplitPaymentData +{ + let charge_request = request.get_split_payment_data(); + if let Some(common_types::payments::SplitPaymentsRequest::StripeSplitPayment( + stripe_split_payment, + )) = charge_request + { + let stripe_charge_response = common_types::payments::StripeChargeResponseData { + charge_id: Some(charge_id), + charge_type: stripe_split_payment.charge_type, + application_fees: stripe_split_payment.application_fees, + transfer_account_id: stripe_split_payment.transfer_account_id, + }; + Some( + common_types::payments::ConnectorChargeResponseData::StripeSplitPayment( + stripe_charge_response, + ), + ) + } else { + None + } +} + + #[cfg(test)] mod test_validate_shipping_address_against_payment_method { #![allow(clippy::unwrap_used)] @@ -4325,32 +4354,4 @@ mod test_validate_shipping_address_against_payment_method { phone: Some(Secret::new(String::from("pbone number"))), } } -} - -pub fn construct_charge_response( - charge_id: String, - request: &T, -) -> Option -where - T: connector_util::SplitPaymentData, -{ - let charge_request = request.get_split_payment_data(); - if let Some(common_types::payments::SplitPaymentsRequest::StripeSplitPayment( - stripe_split_payment, - )) = charge_request - { - let stripe_charge_response = common_types::payments::StripeChargeResponseData { - charge_id: Some(charge_id), - charge_type: stripe_split_payment.charge_type, - application_fees: stripe_split_payment.application_fees, - transfer_account_id: stripe_split_payment.transfer_account_id, - }; - Some( - common_types::payments::ConnectorChargeResponseData::StripeSplitPayment( - stripe_charge_response, - ), - ) - } else { - None - } -} +} \ No newline at end of file diff --git a/crates/router/src/core/utils.rs b/crates/router/src/core/utils.rs index 62be44221d02..386181b91910 100644 --- a/crates/router/src/core/utils.rs +++ b/crates/router/src/core/utils.rs @@ -517,7 +517,7 @@ pub fn get_split_refunds( )) = split_refund_input.refund_request.clone() { super::refunds::validator::validate_adyen_charge_refund( - &adyen_split_payment_response, + adyen_split_payment_response, &split_refund_request, )?; From de7404638597104f8b31b33267b0ff11326c531a Mon Sep 17 00:00:00 2001 From: AkshayaFoiger Date: Wed, 22 Jan 2025 17:24:26 +0530 Subject: [PATCH 20/21] chore: fix error --- crates/common_types/src/refunds.rs | 4 +--- .../src/connectors/boku/transformers.rs | 16 ++++++++-------- .../src/connectors/shift4/transformers.rs | 4 ++-- .../core/payments/operations/payment_response.rs | 2 +- 4 files changed, 12 insertions(+), 14 deletions(-) diff --git a/crates/common_types/src/refunds.rs b/crates/common_types/src/refunds.rs index 14223d32a47b..7259e865575d 100644 --- a/crates/common_types/src/refunds.rs +++ b/crates/common_types/src/refunds.rs @@ -5,8 +5,6 @@ use diesel::{sql_types::Jsonb, AsExpression, FromSqlRow}; use serde::{Deserialize, Serialize}; use utoipa::ToSchema; -use crate::domain as domain_types; - #[derive( Serialize, Deserialize, Debug, Clone, PartialEq, Eq, FromSqlRow, AsExpression, ToSchema, )] @@ -18,7 +16,7 @@ pub enum SplitRefund { /// StripeSplitRefundRequest StripeSplitRefund(StripeSplitRefundRequest), /// AdyenSplitRefundRequest - AdyenSplitRefund(domain_types::AdyenSplitData), + AdyenSplitRefund(crate::domain::AdyenSplitData), } impl_to_sql_from_sql_json!(SplitRefund); diff --git a/crates/hyperswitch_connectors/src/connectors/boku/transformers.rs b/crates/hyperswitch_connectors/src/connectors/boku/transformers.rs index 76cf63aec9a6..baa3575da0d5 100644 --- a/crates/hyperswitch_connectors/src/connectors/boku/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/boku/transformers.rs @@ -264,7 +264,7 @@ pub enum BokuResponse { #[serde(rename_all = "kebab-case")] pub struct BokuPaymentsResponse { charge_status: String, // xml parse only string to fields - charges: String, + charge_id: String, hosted: Option, } @@ -291,7 +291,7 @@ pub struct ChargeResponseData { #[serde(rename_all = "kebab-case")] pub struct SingleChargeResponseData { charge_status: String, - charges: String, + charge_id: String, } impl TryFrom> @@ -344,7 +344,7 @@ fn get_authorize_response( }), }?; - Ok((status, response.charges, redirection_data)) + Ok((status, response.charge_id, redirection_data)) } fn get_psync_response( @@ -352,7 +352,7 @@ fn get_psync_response( ) -> Result<(enums::AttemptStatus, String, Option), errors::ConnectorError> { let status = get_response_status(response.charges.charge.charge_status); - Ok((status, response.charges.charge.charges, None)) + Ok((status, response.charges.charge.charge_id, None)) } // REFUND : @@ -363,7 +363,7 @@ pub struct BokuRefundRequest { merchant_id: Secret, merchant_request_id: String, merchant_refund_id: Secret, - charges: String, + charge_id: String, reason_code: String, } @@ -389,7 +389,7 @@ impl TryFrom<&BokuRouterData<&RefundsRouterData>> for BokuRefundRequest { merchant_id: auth_type.merchant_id, merchant_refund_id: Secret::new(item.router_data.request.refund_id.to_string()), merchant_request_id: Uuid::new_v4().to_string(), - charges: item + charge_id: item .router_data .request .connector_transaction_id @@ -404,7 +404,7 @@ impl TryFrom<&BokuRouterData<&RefundsRouterData>> for BokuRefundRequest { #[derive(Debug, Clone, Deserialize, Serialize)] #[serde(rename = "refund-charge-response")] pub struct RefundResponse { - charges: String, + charge_id: String, refund_status: String, } @@ -423,7 +423,7 @@ impl TryFrom> for RefundsRout ) -> Result { Ok(Self { response: Ok(RefundsResponseData { - connector_refund_id: item.response.charges, + connector_refund_id: item.response.charge_id, refund_status: get_refund_status(item.response.refund_status), }), ..item.data diff --git a/crates/hyperswitch_connectors/src/connectors/shift4/transformers.rs b/crates/hyperswitch_connectors/src/connectors/shift4/transformers.rs index 1b97d495a77c..299372aed74f 100644 --- a/crates/hyperswitch_connectors/src/connectors/shift4/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/shift4/transformers.rs @@ -818,7 +818,7 @@ impl TryFrom TryFrom<&Shift4RouterData<&RefundsRouterData>> for Shift4RefundReques type Error = Error; fn try_from(item: &Shift4RouterData<&RefundsRouterData>) -> Result { Ok(Self { - charges: item.router_data.request.connector_transaction_id.clone(), + charge_id: item.router_data.request.connector_transaction_id.clone(), amount: item.amount.to_owned(), }) } diff --git a/crates/router/src/core/payments/operations/payment_response.rs b/crates/router/src/core/payments/operations/payment_response.rs index 94bd7e35407c..b71349d5f32a 100644 --- a/crates/router/src/core/payments/operations/payment_response.rs +++ b/crates/router/src/core/payments/operations/payment_response.rs @@ -1731,7 +1731,7 @@ async fn payment_response_update_tracker( authentication_data, encoded_data, payment_method_data: additional_payment_method_data, - charge_id: None, //depreciated + charge_id: None, connector_mandate_detail: payment_data .payment_attempt .connector_mandate_detail From c2fbd8e3cd6d50ec538bcc978279df27cbbb41b2 Mon Sep 17 00:00:00 2001 From: "hyperswitch-bot[bot]" <148525504+hyperswitch-bot[bot]@users.noreply.github.com> Date: Wed, 22 Jan 2025 11:58:35 +0000 Subject: [PATCH 21/21] chore: run formatter --- crates/router/src/connector/adyen/transformers.rs | 5 +---- crates/router/src/connector/stripe/transformers.rs | 5 ++--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/crates/router/src/connector/adyen/transformers.rs b/crates/router/src/connector/adyen/transformers.rs index f0424f931224..94fde2955d97 100644 --- a/crates/router/src/connector/adyen/transformers.rs +++ b/crates/router/src/connector/adyen/transformers.rs @@ -4372,10 +4372,7 @@ fn construct_charge_response( let splits: Vec = split_item .iter() .map(|split_item| common_types::domain::AdyenSplitItem { - amount: split_item - .amount - .as_ref() - .map(|amount| amount.value), + amount: split_item.amount.as_ref().map(|amount| amount.value), reference: split_item.reference.clone(), split_type: split_item.split_type.clone(), account: split_item.account.clone(), diff --git a/crates/router/src/connector/stripe/transformers.rs b/crates/router/src/connector/stripe/transformers.rs index 6c6f864511a8..130310b50622 100644 --- a/crates/router/src/connector/stripe/transformers.rs +++ b/crates/router/src/connector/stripe/transformers.rs @@ -4168,7 +4168,7 @@ pub fn construct_charge_response( request: &T, ) -> Option where - T: connector_util::SplitPaymentData + T: connector_util::SplitPaymentData, { let charge_request = request.get_split_payment_data(); if let Some(common_types::payments::SplitPaymentsRequest::StripeSplitPayment( @@ -4191,7 +4191,6 @@ where } } - #[cfg(test)] mod test_validate_shipping_address_against_payment_method { #![allow(clippy::unwrap_used)] @@ -4354,4 +4353,4 @@ mod test_validate_shipping_address_against_payment_method { phone: Some(Secret::new(String::from("pbone number"))), } } -} \ No newline at end of file +}