diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index a17189440954..f78211e9d013 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..a45eb3278be6 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, +} diff --git a/crates/common_types/src/payments.rs b/crates/common_types/src/payments.rs index 0eef7ecaf2b4..5ad9f23de520 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,23 @@ 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..909a5ff7ab38 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) @@ -963,6 +964,7 @@ 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..af87ad6e1c8a 100644 --- a/crates/router/src/connector/stripe/transformers.rs +++ b/crates/router/src/connector/stripe/transformers.rs @@ -1953,7 +1953,9 @@ impl TryFrom<(&types::PaymentsAuthorizeRouterData, MinorUnit)> for PaymentIntent }; (charges, None) } - 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 eda869c3a6ca..4f935c5b6b18 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -6246,24 +6246,41 @@ 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 }); } } } 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 } } }