diff --git a/Cargo.lock b/Cargo.lock index 42add100ad..d6037be06f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1794,8 +1794,10 @@ dependencies = [ "common_utils", "diesel", "euclid", + "masking", "serde", "serde_json", + "time", "utoipa", ] diff --git a/api-reference/v1/openapi_spec_v1.json b/api-reference/v1/openapi_spec_v1.json index e0d888135f..38c60547d9 100644 --- a/api-reference/v1/openapi_spec_v1.json +++ b/api-reference/v1/openapi_spec_v1.json @@ -18194,6 +18194,7 @@ }, "OnlineMandate": { "type": "object", + "description": "Details of online mandate", "required": [ "ip_address", "user_agent" diff --git a/api-reference/v2/openapi_spec_v2.json b/api-reference/v2/openapi_spec_v2.json index 65d1b847f3..2537ae0fcc 100644 --- a/api-reference/v2/openapi_spec_v2.json +++ b/api-reference/v2/openapi_spec_v2.json @@ -14701,6 +14701,7 @@ }, "OnlineMandate": { "type": "object", + "description": "Details of online mandate", "required": [ "ip_address", "user_agent" diff --git a/crates/api_models/src/mandates.rs b/crates/api_models/src/mandates.rs index 2d61a63098..6785232664 100644 --- a/crates/api_models/src/mandates.rs +++ b/crates/api_models/src/mandates.rs @@ -1,9 +1,10 @@ +use common_types::payments as common_payments_types; use masking::Secret; use serde::{Deserialize, Serialize}; use time::PrimitiveDateTime; use utoipa::ToSchema; -use crate::{enums as api_enums, payments}; +use crate::enums as api_enums; #[derive(Default, Debug, Deserialize, Serialize)] pub struct MandateId { @@ -42,7 +43,7 @@ pub struct MandateResponse { pub card: Option, /// Details about the customer’s acceptance #[schema(value_type = Option)] - pub customer_acceptance: Option, + pub customer_acceptance: Option, } #[derive(Default, Debug, Deserialize, Serialize, ToSchema, Clone)] diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index e96806db89..4269f65631 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -10,6 +10,7 @@ use cards::CardNumber; #[cfg(feature = "v2")] use common_enums::enums::PaymentConnectorTransmission; use common_enums::ProductType; +use common_types::payments as common_payments_types; #[cfg(feature = "v1")] use common_types::primitive_wrappers::{ ExtendedAuthorizationAppliedBool, RequestExtendedAuthorizationBool, @@ -1045,7 +1046,7 @@ pub struct PaymentsRequest { /// This "CustomerAcceptance" object is passed during Payments-Confirm request, it enlists the type, time, and mode of acceptance properties related to an acceptance done by the customer. The customer_acceptance sub object is usually passed by the SDK or client. #[schema(value_type = Option)] - pub customer_acceptance: Option, + pub customer_acceptance: Option, /// A unique identifier to link the payment to a mandate. To do Recurring payments after a mandate has been created, pass the mandate_id instead of payment_method_data #[schema(max_length = 64, example = "mandate_iwer89rnjef349dni3")] @@ -1876,7 +1877,8 @@ pub struct MandateData { /// A way to update the mandate's payment method details pub update_mandate_id: Option, /// A consent from the customer to store the payment method - pub customer_acceptance: Option, + #[schema(value_type = Option)] + pub customer_acceptance: Option, /// A way to select the type of mandate used pub mandate_type: Option, } @@ -1925,40 +1927,6 @@ impl Default for MandateType { } } -/// This "CustomerAcceptance" object is passed during Payments-Confirm request, it enlists the type, time, and mode of acceptance properties related to an acceptance done by the customer. The customer_acceptance sub object is usually passed by the SDK or client. -#[derive(Default, Eq, PartialEq, Debug, serde::Deserialize, serde::Serialize, Clone, ToSchema)] -#[serde(deny_unknown_fields)] -pub struct CustomerAcceptance { - /// Type of acceptance provided by the - #[schema(example = "online")] - pub acceptance_type: AcceptanceType, - /// Specifying when the customer acceptance was provided - #[schema(example = "2022-09-10T10:11:12Z")] - #[serde(default, with = "common_utils::custom_serde::iso8601::option")] - pub accepted_at: Option, - /// Information required for online mandate generation - pub online: Option, -} - -#[derive(Default, Debug, serde::Deserialize, serde::Serialize, PartialEq, Eq, Clone, ToSchema)] -#[serde(rename_all = "lowercase")] -/// This is used to indicate if the mandate was accepted online or offline -pub enum AcceptanceType { - Online, - #[default] - Offline, -} - -#[derive(Default, Eq, PartialEq, Debug, serde::Deserialize, serde::Serialize, Clone, ToSchema)] -#[serde(deny_unknown_fields)] -pub struct OnlineMandate { - /// Ip address of the customer machine from which the mandate was created - #[schema(value_type = String, example = "123.32.25.123")] - pub ip_address: Option>, - /// The user-agent of the customer's browser - pub user_agent: String, -} - #[derive(Default, Eq, PartialEq, Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)] pub struct Card { /// The card number @@ -5379,7 +5347,7 @@ pub struct PaymentsConfirmIntentRequest { /// This "CustomerAcceptance" object is passed during Payments-Confirm request, it enlists the type, time, and mode of acceptance properties related to an acceptance done by the customer. The customer_acceptance sub object is usually passed by the SDK or client. #[schema(value_type = Option)] - pub customer_acceptance: Option, + pub customer_acceptance: Option, /// Additional details required by 3DS 2.0 #[schema(value_type = Option)] @@ -5551,7 +5519,7 @@ pub struct PaymentsRequest { /// This "CustomerAcceptance" object is passed during Payments-Confirm request, it enlists the type, time, and mode of acceptance properties related to an acceptance done by the customer. The customer_acceptance sub object is usually passed by the SDK or client. #[schema(value_type = Option)] - pub customer_acceptance: Option, + pub customer_acceptance: Option, /// Additional details required by 3DS 2.0 #[schema(value_type = Option)] diff --git a/crates/common_types/Cargo.toml b/crates/common_types/Cargo.toml index 0734a8860a..7aec031470 100644 --- a/crates/common_types/Cargo.toml +++ b/crates/common_types/Cargo.toml @@ -17,10 +17,12 @@ diesel = "2.2.10" serde = { version = "1.0.219", features = ["derive"] } serde_json = "1.0.140" utoipa = { version = "4.2.3", features = ["preserve_order", "preserve_path_order"] } +time = { version = "0.3.35", features = ["serde", "serde-well-known", "std"] } common_enums = { version = "0.1.0", path = "../common_enums" } common_utils = { version = "0.1.0", path = "../common_utils"} euclid = { version = "0.1.0", path = "../euclid" } +masking = { version = "0.1.0", path = "../masking" } [lints] workspace = true diff --git a/crates/common_types/src/payments.rs b/crates/common_types/src/payments.rs index 1a73e2f978..e0ea52abc7 100644 --- a/crates/common_types/src/payments.rs +++ b/crates/common_types/src/payments.rs @@ -3,13 +3,15 @@ use std::collections::HashMap; use common_enums::enums; -use common_utils::{errors, events, impl_to_sql_from_sql_json, types::MinorUnit}; +use common_utils::{date_time, errors, events, impl_to_sql_from_sql_json, pii, types::MinorUnit}; use diesel::{sql_types::Jsonb, AsExpression, FromSqlRow}; use euclid::frontend::{ ast::Program, dir::{DirKeyKind, EuclidDirFilter}, }; +use masking::{PeekInterface, Secret}; use serde::{Deserialize, Serialize}; +use time::PrimitiveDateTime; use utoipa::ToSchema; use crate::domain::{AdyenSplitData, XenditSplitSubMerchantData}; @@ -100,6 +102,92 @@ impl EuclidDirFilter for ConditionalConfigs { impl_to_sql_from_sql_json!(ConditionalConfigs); +/// This "CustomerAcceptance" object is passed during Payments-Confirm request, it enlists the type, time, and mode of acceptance properties related to an acceptance done by the customer. The customer_acceptance sub object is usually passed by the SDK or client. +#[derive( + Default, + Eq, + PartialEq, + Debug, + serde::Deserialize, + serde::Serialize, + Clone, + AsExpression, + ToSchema, +)] +#[serde(deny_unknown_fields)] +#[diesel(sql_type = Jsonb)] +pub struct CustomerAcceptance { + /// Type of acceptance provided by the + #[schema(example = "online")] + pub acceptance_type: AcceptanceType, + /// Specifying when the customer acceptance was provided + #[schema(example = "2022-09-10T10:11:12Z")] + #[serde(default, with = "common_utils::custom_serde::iso8601::option")] + pub accepted_at: Option, + /// Information required for online mandate generation + pub online: Option, +} + +impl_to_sql_from_sql_json!(CustomerAcceptance); + +impl CustomerAcceptance { + /// Get the IP address + pub fn get_ip_address(&self) -> Option { + self.online + .as_ref() + .and_then(|data| data.ip_address.as_ref().map(|ip| ip.peek().to_owned())) + } + + /// Get the User Agent + pub fn get_user_agent(&self) -> Option { + self.online.as_ref().map(|data| data.user_agent.clone()) + } + + /// Get when the customer acceptance was provided + pub fn get_accepted_at(&self) -> PrimitiveDateTime { + self.accepted_at.unwrap_or_else(date_time::now) + } +} + +impl masking::SerializableSecret for CustomerAcceptance {} + +#[derive( + Default, Debug, serde::Deserialize, serde::Serialize, PartialEq, Eq, Clone, Copy, ToSchema, +)] +#[serde(rename_all = "lowercase")] +/// This is used to indicate if the mandate was accepted online or offline +pub enum AcceptanceType { + /// Online + Online, + /// Offline + #[default] + Offline, +} + +#[derive( + Default, + Eq, + PartialEq, + Debug, + serde::Deserialize, + serde::Serialize, + AsExpression, + Clone, + ToSchema, +)] +#[serde(deny_unknown_fields)] +/// Details of online mandate +#[diesel(sql_type = Jsonb)] +pub struct OnlineMandate { + /// Ip address of the customer machine from which the mandate was created + #[schema(value_type = String, example = "123.32.25.123")] + pub ip_address: Option>, + /// The user-agent of the customer's browser + pub user_agent: String, +} + +impl_to_sql_from_sql_json!(OnlineMandate); + #[derive(Serialize, Deserialize, Debug, Clone, FromSqlRow, AsExpression, ToSchema)] #[diesel(sql_type = Jsonb)] /// DecisionManagerRecord diff --git a/crates/diesel_models/src/payment_attempt.rs b/crates/diesel_models/src/payment_attempt.rs index 9e20ca7407..95fb600adc 100644 --- a/crates/diesel_models/src/payment_attempt.rs +++ b/crates/diesel_models/src/payment_attempt.rs @@ -1,3 +1,5 @@ +#[cfg(feature = "v2")] +use common_types::payments as common_payments_types; use common_types::primitive_wrappers::{ ExtendedAuthorizationAppliedBool, RequestExtendedAuthorizationBool, }; @@ -78,7 +80,7 @@ pub struct PaymentAttempt { pub fingerprint_id: Option, pub client_source: Option, pub client_version: Option, - pub customer_acceptance: Option, + pub customer_acceptance: Option>, pub profile_id: id_type::ProfileId, pub organization_id: id_type::OrganizationId, pub card_network: Option, @@ -319,7 +321,7 @@ pub struct PaymentAttemptNew { pub payment_method_billing_address: Option, pub client_source: Option, pub client_version: Option, - pub customer_acceptance: Option, + pub customer_acceptance: Option>, pub profile_id: id_type::ProfileId, pub organization_id: id_type::OrganizationId, pub card_network: Option, diff --git a/crates/hyperswitch_connectors/src/connectors/stripe/transformers.rs b/crates/hyperswitch_connectors/src/connectors/stripe/transformers.rs index 353d941ca6..b6f263373b 100644 --- a/crates/hyperswitch_connectors/src/connectors/stripe/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/stripe/transformers.rs @@ -2,7 +2,7 @@ use std::{collections::HashMap, ops::Deref}; use api_models::{self, enums as api_enums, payments}; use common_enums::{enums, AttemptStatus, PaymentChargeType, StripeChargeType}; -use common_types::payments::SplitPaymentsRequest; +use common_types::payments::{AcceptanceType, SplitPaymentsRequest}; use common_utils::{ collect_missing_value_keys, errors::CustomResult, @@ -13,7 +13,6 @@ use common_utils::{ }; use error_stack::ResultExt; use hyperswitch_domain_models::{ - mandates::AcceptanceType, payment_method_data::{ self, BankRedirectData, Card, CardRedirectData, GiftCardData, GooglePayWalletData, PayLaterData, PaymentMethodData, VoucherData, WalletData, diff --git a/crates/hyperswitch_domain_models/src/mandates.rs b/crates/hyperswitch_domain_models/src/mandates.rs index 5e5b9e1828..264ed0c6d8 100644 --- a/crates/hyperswitch_domain_models/src/mandates.rs +++ b/crates/hyperswitch_domain_models/src/mandates.rs @@ -1,11 +1,10 @@ use std::collections::HashMap; use api_models::payments::{ - AcceptanceType as ApiAcceptanceType, CustomerAcceptance as ApiCustomerAcceptance, MandateAmountData as ApiMandateAmountData, MandateData as ApiMandateData, MandateType, - OnlineMandate as ApiOnlineMandate, }; use common_enums::Currency; +use common_types::payments as common_payments_types; use common_utils::{ date_time, errors::{CustomResult, ParsingError}, @@ -13,7 +12,6 @@ use common_utils::{ types::MinorUnit, }; use error_stack::ResultExt; -use masking::{PeekInterface, Secret}; use time::PrimitiveDateTime; #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] @@ -61,39 +59,11 @@ pub struct MandateData { /// A way to update the mandate's payment method details pub update_mandate_id: Option, /// A consent from the customer to store the payment method - pub customer_acceptance: Option, + pub customer_acceptance: Option, /// A way to select the type of mandate used pub mandate_type: Option, } -#[derive(Default, Eq, PartialEq, Debug, Clone, serde::Deserialize, serde::Serialize)] -pub struct CustomerAcceptance { - /// Type of acceptance provided by the - pub acceptance_type: AcceptanceType, - /// Specifying when the customer acceptance was provided - #[serde(with = "common_utils::custom_serde::iso8601::option")] - pub accepted_at: Option, - /// Information required for online mandate generation - pub online: Option, -} - -#[derive(Default, Debug, PartialEq, Eq, Clone, serde::Deserialize, serde::Serialize)] -#[serde(rename_all = "lowercase")] -pub enum AcceptanceType { - Online, - #[default] - Offline, -} - -#[derive(Default, Eq, PartialEq, Debug, Clone, serde::Deserialize, serde::Serialize)] -pub struct OnlineMandate { - /// Ip address of the customer machine from which the mandate was created - #[serde(skip_deserializing)] - pub ip_address: Option>, - /// The user-agent of the customer's browser - pub user_agent: String, -} - impl From for MandateDataType { fn from(mandate_type: MandateType) -> Self { match mandate_type { @@ -168,83 +138,13 @@ impl From for MandateAmountData { impl From for MandateData { fn from(value: ApiMandateData) -> Self { Self { - customer_acceptance: value.customer_acceptance.map(|d| d.into()), + customer_acceptance: value.customer_acceptance, mandate_type: value.mandate_type.map(|d| d.into()), update_mandate_id: value.update_mandate_id, } } } -impl From for CustomerAcceptance { - fn from(value: ApiCustomerAcceptance) -> Self { - Self { - acceptance_type: value.acceptance_type.into(), - accepted_at: value.accepted_at, - online: value.online.map(|d| d.into()), - } - } -} - -impl From for ApiCustomerAcceptance { - fn from(value: CustomerAcceptance) -> Self { - Self { - acceptance_type: value.acceptance_type.into(), - accepted_at: value.accepted_at, - online: value.online.map(|d| d.into()), - } - } -} - -impl From for AcceptanceType { - fn from(value: ApiAcceptanceType) -> Self { - match value { - ApiAcceptanceType::Online => Self::Online, - ApiAcceptanceType::Offline => Self::Offline, - } - } -} -impl From for ApiAcceptanceType { - fn from(value: AcceptanceType) -> Self { - match value { - AcceptanceType::Online => Self::Online, - AcceptanceType::Offline => Self::Offline, - } - } -} - -impl From for OnlineMandate { - fn from(value: ApiOnlineMandate) -> Self { - Self { - ip_address: value.ip_address, - user_agent: value.user_agent, - } - } -} -impl From for ApiOnlineMandate { - fn from(value: OnlineMandate) -> Self { - Self { - ip_address: value.ip_address, - user_agent: value.user_agent, - } - } -} - -impl CustomerAcceptance { - pub fn get_ip_address(&self) -> Option { - self.online - .as_ref() - .and_then(|data| data.ip_address.as_ref().map(|ip| ip.peek().to_owned())) - } - - pub fn get_user_agent(&self) -> Option { - self.online.as_ref().map(|data| data.user_agent.clone()) - } - - pub fn get_accepted_at(&self) -> PrimitiveDateTime { - self.accepted_at.unwrap_or_else(date_time::now) - } -} - impl MandateAmountData { pub fn get_end_date( &self, diff --git a/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs b/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs index 98b93d6b6f..2a8e8daa67 100644 --- a/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs +++ b/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs @@ -1,6 +1,8 @@ #[cfg(all(feature = "v1", feature = "olap"))] use api_models::enums::Connector; use common_enums as storage_enums; +#[cfg(feature = "v2")] +use common_types::payments as common_payments_types; #[cfg(feature = "v1")] use common_types::primitive_wrappers::{ ExtendedAuthorizationAppliedBool, RequestExtendedAuthorizationBool, @@ -440,8 +442,7 @@ pub struct PaymentAttempt { pub fingerprint_id: Option, pub client_source: Option, pub client_version: Option, - // TODO: use a type here instead of value - pub customer_acceptance: Option, + pub customer_acceptance: Option>, /// The profile id for the payment attempt. This will be derived from payment intent. pub profile_id: id_type::ProfileId, /// The organization id for the payment attempt. This will be derived from payment intent. @@ -590,14 +591,7 @@ impl PaymentAttempt { charges: None, client_source: None, client_version: None, - customer_acceptance: request - .customer_acceptance - .as_ref() - .map(Encode::encode_to_value) - .transpose() - .change_context(errors::api_error_response::ApiErrorResponse::InternalServerError) - .attach_printable("Unable to encode customer_acceptance")? - .map(Secret::new), + customer_acceptance: request.customer_acceptance.clone().map(Secret::new), profile_id: payment_intent.profile_id.clone(), organization_id: payment_intent.organization_id.clone(), payment_method_type: request.payment_method_type, diff --git a/crates/hyperswitch_domain_models/src/router_request_types.rs b/crates/hyperswitch_domain_models/src/router_request_types.rs index 06932fb126..e811b872c8 100644 --- a/crates/hyperswitch_domain_models/src/router_request_types.rs +++ b/crates/hyperswitch_domain_models/src/router_request_types.rs @@ -3,6 +3,7 @@ pub mod fraud_check; pub mod revenue_recovery; pub mod unified_authentication_service; use api_models::payments::{AdditionalPaymentData, RequestSurchargeDetails}; +use common_types::payments as common_payments_types; use common_utils::{consts, errors, ext_traits::OptionExt, id_type, pii, types::MinorUnit}; use diesel_models::{enums as storage_enums, types::OrderDetailsWithAmount}; use error_stack::ResultExt; @@ -46,7 +47,7 @@ pub struct PaymentsAuthorizeData { pub setup_future_usage: Option, pub mandate_id: Option, pub off_session: Option, - pub customer_acceptance: Option, + pub customer_acceptance: Option, pub setup_mandate_details: Option, pub browser_info: Option, pub order_details: Option>, @@ -478,7 +479,7 @@ pub struct CompleteAuthorizeData { pub connector_meta: Option, pub complete_authorize_url: Option, pub metadata: Option, - pub customer_acceptance: Option, + pub customer_acceptance: Option, // New amount for amount frame work pub minor_amount: MinorUnit, pub merchant_account_id: Option>, @@ -969,7 +970,7 @@ pub struct SetupMandateRequestData { pub amount: Option, pub confirm: bool, pub statement_descriptor_suffix: Option, - pub customer_acceptance: Option, + pub customer_acceptance: Option, pub mandate_id: Option, pub setup_future_usage: Option, pub off_session: Option, diff --git a/crates/openapi/src/openapi.rs b/crates/openapi/src/openapi.rs index 0e420ab794..11fb349a33 100644 --- a/crates/openapi/src/openapi.rs +++ b/crates/openapi/src/openapi.rs @@ -234,6 +234,9 @@ Never share your secret api keys. Keep them guarded and secure. common_types::payments::StripeSplitPaymentRequest, common_types::domain::AdyenSplitData, common_types::domain::AdyenSplitItem, + common_types::payments::AcceptanceType, + common_types::payments::CustomerAcceptance, + common_types::payments::OnlineMandate, common_types::payments::XenditSplitRequest, common_types::payments::XenditSplitRoute, common_types::payments::XenditChargeResponseData, @@ -450,13 +453,10 @@ Never share your secret api keys. Keep them guarded and secure. api_models::payments::PaymentMethodData, api_models::payments::PaymentMethodDataRequest, api_models::payments::MandateType, - api_models::payments::AcceptanceType, api_models::payments::MandateAmountData, - api_models::payments::OnlineMandate, api_models::payments::Card, api_models::payments::CardRedirectData, api_models::payments::CardToken, - api_models::payments::CustomerAcceptance, api_models::payments::PaymentsRequest, api_models::payments::PaymentsCreateRequest, api_models::payments::PaymentsUpdateRequest, diff --git a/crates/openapi/src/openapi_v2.rs b/crates/openapi/src/openapi_v2.rs index d55d5829bd..bdf63e1a1e 100644 --- a/crates/openapi/src/openapi_v2.rs +++ b/crates/openapi/src/openapi_v2.rs @@ -181,6 +181,9 @@ Never share your secret api keys. Keep them guarded and secure. common_types::payments::SplitPaymentsRequest, common_types::payments::StripeSplitPaymentRequest, common_types::domain::AdyenSplitData, + common_types::payments::AcceptanceType, + common_types::payments::CustomerAcceptance, + common_types::payments::OnlineMandate, common_types::payments::XenditSplitRequest, common_types::payments::XenditSplitRoute, common_types::payments::XenditChargeResponseData, @@ -412,13 +415,10 @@ Never share your secret api keys. Keep them guarded and secure. api_models::payments::PaymentMethodData, api_models::payments::PaymentMethodDataRequest, api_models::payments::MandateType, - api_models::payments::AcceptanceType, api_models::payments::MandateAmountData, - api_models::payments::OnlineMandate, api_models::payments::Card, api_models::payments::CardRedirectData, api_models::payments::CardToken, - api_models::payments::CustomerAcceptance, api_models::payments::ConnectorTokenDetails, api_models::payments::PaymentsRequest, api_models::payments::PaymentsResponse, diff --git a/crates/router/src/compatibility/stripe/payment_intents/types.rs b/crates/router/src/compatibility/stripe/payment_intents/types.rs index c2d2b33b28..e8813fad68 100644 --- a/crates/router/src/compatibility/stripe/payment_intents/types.rs +++ b/crates/router/src/compatibility/stripe/payment_intents/types.rs @@ -1,6 +1,7 @@ use std::str::FromStr; use api_models::payments; +use common_types::payments as common_payments_types; use common_utils::{ crypto::Encryptable, date_time, @@ -765,16 +766,15 @@ impl ForeignTryFrom<(Option, Option)> for Option Option<&hyperswitch_domain_models::mandates::MandateData>; - fn get_customer_acceptance(&self) -> Option; + fn get_customer_acceptance(&self) -> Option; } diff --git a/crates/router/src/core/mandate/helpers.rs b/crates/router/src/core/mandate/helpers.rs index 14a733d2eb..298c737c6d 100644 --- a/crates/router/src/core/mandate/helpers.rs +++ b/crates/router/src/core/mandate/helpers.rs @@ -1,5 +1,6 @@ use api_models::payments as api_payments; use common_enums::enums; +use common_types::payments as common_payments_types; use common_utils::errors::CustomResult; use diesel_models::Mandate; use error_stack::ResultExt; @@ -49,7 +50,7 @@ pub fn get_mandate_type( mandate_data: Option, off_session: Option, setup_future_usage: Option, - customer_acceptance: Option, + customer_acceptance: Option, token: Option, payment_method: Option, ) -> CustomResult, errors::ValidationError> { diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs index 1d4521661b..067a5703c2 100644 --- a/crates/router/src/core/payments.rs +++ b/crates/router/src/core/payments.rs @@ -33,6 +33,7 @@ use api_models::{ payments::{self as payments_api}, }; pub use common_enums::enums::CallConnectorAction; +use common_types::payments as common_payments_types; use common_utils::{ ext_traits::{AsyncExt, StringExt}, id_type, pii, @@ -51,7 +52,7 @@ use hyperswitch_domain_models::payments::{ #[cfg(feature = "v2")] use hyperswitch_domain_models::router_response_types::RedirectForm; pub use hyperswitch_domain_models::{ - mandates::{CustomerAcceptance, MandateData}, + mandates::MandateData, payment_address::PaymentAddress, payments::{self as domain_payments, HeaderPayload}, router_data::{PaymentMethodToken, RouterData}, @@ -5960,7 +5961,7 @@ where pub mandate_connector: Option, pub currency: storage_enums::Currency, pub setup_mandate: Option, - pub customer_acceptance: Option, + pub customer_acceptance: Option, pub address: PaymentAddress, pub token: Option, pub token_data: Option, diff --git a/crates/router/src/core/payments/flows.rs b/crates/router/src/core/payments/flows.rs index fa951af010..2b68120274 100644 --- a/crates/router/src/core/payments/flows.rs +++ b/crates/router/src/core/payments/flows.rs @@ -13,13 +13,12 @@ pub mod setup_mandate_flow; pub mod update_metadata_flow; use async_trait::async_trait; +use common_types::payments::CustomerAcceptance; #[cfg(all(feature = "v2", feature = "revenue_recovery"))] use hyperswitch_domain_models::router_flow_types::{ BillingConnectorInvoiceSync, BillingConnectorPaymentsSync, RecoveryRecordBack, }; -use hyperswitch_domain_models::{ - mandates::CustomerAcceptance, router_request_types::PaymentsCaptureData, -}; +use hyperswitch_domain_models::router_request_types::PaymentsCaptureData; use crate::{ core::{ diff --git a/crates/router/src/core/payments/flows/authorize_flow.rs b/crates/router/src/core/payments/flows/authorize_flow.rs index ee27620917..318e69d7ac 100644 --- a/crates/router/src/core/payments/flows/authorize_flow.rs +++ b/crates/router/src/core/payments/flows/authorize_flow.rs @@ -1,5 +1,6 @@ use async_trait::async_trait; use common_enums as enums; +use common_types::payments as common_payments_types; use hyperswitch_domain_models::errors::api_error_response::ApiErrorResponse; #[cfg(feature = "v2")] use hyperswitch_domain_models::payments::PaymentConfirmData; @@ -498,8 +499,8 @@ impl mandate::MandateBehaviour for types::PaymentsAuthorizeData { fn set_mandate_id(&mut self, new_mandate_id: Option) { self.mandate_id = new_mandate_id; } - fn get_customer_acceptance(&self) -> Option { - self.customer_acceptance.clone().map(From::from) + fn get_customer_acceptance(&self) -> Option { + self.customer_acceptance.clone() } } diff --git a/crates/router/src/core/payments/flows/setup_mandate_flow.rs b/crates/router/src/core/payments/flows/setup_mandate_flow.rs index d4722a05c8..a5bcdb4f55 100644 --- a/crates/router/src/core/payments/flows/setup_mandate_flow.rs +++ b/crates/router/src/core/payments/flows/setup_mandate_flow.rs @@ -1,4 +1,5 @@ use async_trait::async_trait; +use common_types::payments as common_payments_types; use router_env::logger; use super::{ConstructFlowSpecificData, Feature}; @@ -247,7 +248,7 @@ impl mandate::MandateBehaviour for types::SetupMandateRequestData { ) -> Option<&hyperswitch_domain_models::mandates::MandateData> { self.setup_mandate_details.as_ref() } - fn get_customer_acceptance(&self) -> Option { - self.customer_acceptance.clone().map(From::from) + fn get_customer_acceptance(&self) -> Option { + self.customer_acceptance.clone() } } diff --git a/crates/router/src/core/payments/operations/payment_complete_authorize.rs b/crates/router/src/core/payments/operations/payment_complete_authorize.rs index 199b4faf62..3ce888e657 100644 --- a/crates/router/src/core/payments/operations/payment_complete_authorize.rs +++ b/crates/router/src/core/payments/operations/payment_complete_authorize.rs @@ -11,16 +11,13 @@ use crate::{ core::{ errors::{self, CustomResult, RouterResult, StorageErrorExt}, mandate::helpers as m_helpers, - payments::{ - self, helpers, operations, CustomerAcceptance, CustomerDetails, PaymentAddress, - PaymentData, - }, + payments::{self, helpers, operations, CustomerDetails, PaymentAddress, PaymentData}, }, events::audit_events::{AuditEvent, AuditEventType}, routes::{app::ReqState, SessionState}, services, types::{ - api::{self, PaymentIdTypeExt}, + api::{self, CustomerAcceptance, PaymentIdTypeExt}, domain, storage::{self, enums as storage_enums}, }, @@ -139,11 +136,8 @@ impl GetTracker, api::PaymentsRequest> payment_intent.customer_id.as_ref(), )) .await?; - let customer_acceptance: Option = request - .customer_acceptance - .clone() - .map(From::from) - .or(payment_method_info + let customer_acceptance: Option = + request.customer_acceptance.clone().or(payment_method_info .clone() .map(|pm| { pm.customer_acceptance diff --git a/crates/router/src/core/payments/operations/payment_confirm.rs b/crates/router/src/core/payments/operations/payment_confirm.rs index 6324c37bdf..4dbefe6c9d 100644 --- a/crates/router/src/core/payments/operations/payment_confirm.rs +++ b/crates/router/src/core/payments/operations/payment_confirm.rs @@ -789,7 +789,7 @@ impl GetTracker, api::PaymentsRequest> mandate_id: mandate_id.clone(), mandate_connector, setup_mandate, - customer_acceptance: customer_acceptance.map(From::from), + customer_acceptance, token, address: unified_address, token_data, diff --git a/crates/router/src/core/payments/operations/payment_create.rs b/crates/router/src/core/payments/operations/payment_create.rs index 43e9c39c56..4c463c74ed 100644 --- a/crates/router/src/core/payments/operations/payment_create.rs +++ b/crates/router/src/core/payments/operations/payment_create.rs @@ -5,6 +5,7 @@ use api_models::{ payments::GetAddressFromPaymentMethodData, }; use async_trait::async_trait; +use common_types::payments as common_payments_types; use common_utils::{ ext_traits::{AsyncExt, Encode, ValueExt}, type_name, @@ -143,7 +144,7 @@ impl GetTracker, api::PaymentsRequest> id: profile_id.get_string_repr().to_owned(), })? }; - let customer_acceptance = request.customer_acceptance.clone().map(From::from); + let customer_acceptance = request.customer_acceptance.clone(); let recurring_details = request.recurring_details.clone(); @@ -1116,7 +1117,7 @@ impl PaymentCreate { payment_method_info: &Option, key_store: &domain::MerchantKeyStore, profile_id: common_utils::id_type::ProfileId, - customer_acceptance: &Option, + customer_acceptance: &Option, storage_scheme: enums::MerchantStorageScheme, ) -> RouterResult<( storage::PaymentAttemptNew, diff --git a/crates/router/src/core/payments/operations/payment_update.rs b/crates/router/src/core/payments/operations/payment_update.rs index b42bdd12ff..2299acbe30 100644 --- a/crates/router/src/core/payments/operations/payment_update.rs +++ b/crates/router/src/core/payments/operations/payment_update.rs @@ -129,7 +129,7 @@ impl GetTracker, api::PaymentsRequest> .await .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?; - let customer_acceptance = request.customer_acceptance.clone().map(From::from); + let customer_acceptance = request.customer_acceptance.clone(); let recurring_details = request.recurring_details.clone(); let mandate_type = m_helpers::get_mandate_type( diff --git a/crates/router/src/core/payments/routing.rs b/crates/router/src/core/payments/routing.rs index ef7d1d46f5..4cc667bdc8 100644 --- a/crates/router/src/core/payments/routing.rs +++ b/crates/router/src/core/payments/routing.rs @@ -15,6 +15,7 @@ use api_models::{ enums::{self as api_enums, CountryAlpha2}, routing::ConnectorSelection, }; +use common_types::payments as common_payments_types; #[cfg(all(feature = "v1", feature = "dynamic_routing"))] use common_utils::ext_traits::AsyncExt; use diesel_models::enums as storage_enums; @@ -213,10 +214,10 @@ pub fn make_dsl_input( .customer_acceptance .as_ref() .map(|customer_accept| match customer_accept.acceptance_type { - hyperswitch_domain_models::mandates::AcceptanceType::Online => { + common_payments_types::AcceptanceType::Online => { euclid_enums::MandateAcceptanceType::Online } - hyperswitch_domain_models::mandates::AcceptanceType::Offline => { + common_payments_types::AcceptanceType::Offline => { euclid_enums::MandateAcceptanceType::Offline } }) @@ -328,10 +329,10 @@ pub fn make_dsl_input( .customer_acceptance .as_ref() .map(|cat| match cat.acceptance_type { - hyperswitch_domain_models::mandates::AcceptanceType::Online => { + common_payments_types::AcceptanceType::Online => { euclid_enums::MandateAcceptanceType::Online } - hyperswitch_domain_models::mandates::AcceptanceType::Offline => { + common_payments_types::AcceptanceType::Offline => { euclid_enums::MandateAcceptanceType::Offline } }) diff --git a/crates/router/src/core/payments/routing/transformers.rs b/crates/router/src/core/payments/routing/transformers.rs index 026807f397..7e66773224 100644 --- a/crates/router/src/core/payments/routing/transformers.rs +++ b/crates/router/src/core/payments/routing/transformers.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; use api_models::{self, routing as routing_types}; +use common_types::payments as common_payments_types; use diesel_models::enums as storage_enums; use euclid::{enums as dsl_enums, frontend::ast as dsl_ast}; use kgraph_utils::types; @@ -31,11 +32,11 @@ impl ForeignFrom for Option for dsl_enums::MandateAcceptanceType { - fn foreign_from(from: api_models::payments::AcceptanceType) -> Self { +impl ForeignFrom for dsl_enums::MandateAcceptanceType { + fn foreign_from(from: common_payments_types::AcceptanceType) -> Self { match from { - api_models::payments::AcceptanceType::Online => Self::Online, - api_models::payments::AcceptanceType::Offline => Self::Offline, + common_payments_types::AcceptanceType::Online => Self::Online, + common_payments_types::AcceptanceType::Offline => Self::Offline, } } } diff --git a/crates/router/src/core/payments/session_operation.rs b/crates/router/src/core/payments/session_operation.rs index 3ed015309e..d24845d4b5 100644 --- a/crates/router/src/core/payments/session_operation.rs +++ b/crates/router/src/core/payments/session_operation.rs @@ -4,7 +4,7 @@ pub use common_enums::enums::CallConnectorAction; use common_utils::id_type; use error_stack::ResultExt; pub use hyperswitch_domain_models::{ - mandates::{CustomerAcceptance, MandateData}, + mandates::MandateData, payment_address::PaymentAddress, payments::{HeaderPayload, PaymentIntentData}, router_data::{PaymentMethodToken, RouterData}, diff --git a/crates/router/src/core/payments/tokenization.rs b/crates/router/src/core/payments/tokenization.rs index f758066207..b88476e19d 100644 --- a/crates/router/src/core/payments/tokenization.rs +++ b/crates/router/src/core/payments/tokenization.rs @@ -168,7 +168,7 @@ where let customer_acceptance = save_payment_method_data .request .get_customer_acceptance() - .or(mandate_data_customer_acceptance.clone().map(From::from)) + .or(mandate_data_customer_acceptance.clone()) .map(|ca| ca.encode_to_value()) .transpose() .change_context(errors::ApiErrorResponse::InternalServerError) diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index 23b856a8b9..f5c06afe17 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -2754,24 +2754,8 @@ where }); let mandate_data = payment_data.get_setup_mandate().map(|d| api::MandateData { - customer_acceptance: d - .customer_acceptance - .clone() - .map(|d| api::CustomerAcceptance { - acceptance_type: match d.acceptance_type { - hyperswitch_domain_models::mandates::AcceptanceType::Online => { - api::AcceptanceType::Online - } - hyperswitch_domain_models::mandates::AcceptanceType::Offline => { - api::AcceptanceType::Offline - } - }, - accepted_at: d.accepted_at, - online: d.online.map(|d| api::OnlineMandate { - ip_address: d.ip_address, - user_agent: d.user_agent, - }), - }), + customer_acceptance: d.customer_acceptance.clone(), + mandate_type: d.mandate_type.clone().map(|d| match d { hyperswitch_domain_models::mandates::MandateDataType::MultiUse(Some(i)) => { api::MandateType::MultiUse(Some(api::MandateAmountData { diff --git a/crates/router/src/core/payments/vault_session.rs b/crates/router/src/core/payments/vault_session.rs index db77d6a999..10b965786e 100644 --- a/crates/router/src/core/payments/vault_session.rs +++ b/crates/router/src/core/payments/vault_session.rs @@ -4,7 +4,7 @@ pub use common_enums::enums::CallConnectorAction; use common_utils::id_type; use error_stack::ResultExt; pub use hyperswitch_domain_models::{ - mandates::{CustomerAcceptance, MandateData}, + mandates::MandateData, payment_address::PaymentAddress, payments::{HeaderPayload, PaymentIntentData}, router_data::{PaymentMethodToken, RouterData}, diff --git a/crates/router/src/services/kafka/payment_attempt.rs b/crates/router/src/services/kafka/payment_attempt.rs index ba34b18b6a..f51e5a12d2 100644 --- a/crates/router/src/services/kafka/payment_attempt.rs +++ b/crates/router/src/services/kafka/payment_attempt.rs @@ -191,7 +191,7 @@ pub struct KafkaPaymentAttempt<'a> { pub authentication_connector: Option, pub authentication_id: Option, pub fingerprint_id: Option, - pub customer_acceptance: Option<&'a masking::Secret>, + pub customer_acceptance: Option<&'a masking::Secret>, pub shipping_cost: Option, pub order_tax_amount: Option, pub charges: Option, diff --git a/crates/router/src/services/kafka/payment_attempt_event.rs b/crates/router/src/services/kafka/payment_attempt_event.rs index 7cd70f9a73..e2a88e2c29 100644 --- a/crates/router/src/services/kafka/payment_attempt_event.rs +++ b/crates/router/src/services/kafka/payment_attempt_event.rs @@ -193,7 +193,7 @@ pub struct KafkaPaymentAttemptEvent<'a> { pub authentication_connector: Option, pub authentication_id: Option, pub fingerprint_id: Option, - pub customer_acceptance: Option<&'a masking::Secret>, + pub customer_acceptance: Option<&'a masking::Secret>, pub shipping_cost: Option, pub order_tax_amount: Option, pub charges: Option, diff --git a/crates/router/src/types/api/payments.rs b/crates/router/src/types/api/payments.rs index 725a821eba..62738680b1 100644 --- a/crates/router/src/types/api/payments.rs +++ b/crates/router/src/types/api/payments.rs @@ -12,26 +12,27 @@ pub use api_models::{ ConnectorFeatureMatrixResponse, FeatureMatrixListResponse, FeatureMatrixRequest, }, payments::{ - AcceptanceType, Address, AddressDetails, Amount, AuthenticationForStartResponse, Card, - CryptoData, CustomerAcceptance, CustomerDetails, CustomerDetailsResponse, - HyperswitchVaultSessionDetails, MandateAmountData, MandateData, MandateTransactionType, - MandateType, MandateValidationFields, NextActionType, OnlineMandate, - OpenBankingSessionToken, PayLaterData, PaymentIdType, PaymentListConstraints, - PaymentListFilters, PaymentListFiltersV2, PaymentMethodData, PaymentMethodDataRequest, - PaymentMethodDataResponse, PaymentOp, PaymentRetrieveBody, - PaymentRetrieveBodyWithCredentials, PaymentsAggregateResponse, PaymentsApproveRequest, - PaymentsCancelRequest, PaymentsCaptureRequest, PaymentsCompleteAuthorizeRequest, - PaymentsDynamicTaxCalculationRequest, PaymentsDynamicTaxCalculationResponse, - PaymentsExternalAuthenticationRequest, PaymentsIncrementalAuthorizationRequest, - PaymentsManualUpdateRequest, PaymentsPostSessionTokensRequest, - PaymentsPostSessionTokensResponse, PaymentsRedirectRequest, PaymentsRedirectionResponse, - PaymentsRejectRequest, PaymentsRequest, PaymentsResponse, PaymentsResponseForm, - PaymentsRetrieveRequest, PaymentsSessionRequest, PaymentsSessionResponse, - PaymentsStartRequest, PaymentsUpdateMetadataRequest, PaymentsUpdateMetadataResponse, - PgRedirectResponse, PhoneDetails, RedirectionResponse, SessionToken, UrlDetails, - VaultSessionDetails, VerifyRequest, VerifyResponse, VgsSessionDetails, WalletData, + Address, AddressDetails, Amount, AuthenticationForStartResponse, Card, CryptoData, + CustomerDetails, CustomerDetailsResponse, HyperswitchVaultSessionDetails, + MandateAmountData, MandateData, MandateTransactionType, MandateType, + MandateValidationFields, NextActionType, OpenBankingSessionToken, PayLaterData, + PaymentIdType, PaymentListConstraints, PaymentListFilters, PaymentListFiltersV2, + PaymentMethodData, PaymentMethodDataRequest, PaymentMethodDataResponse, PaymentOp, + PaymentRetrieveBody, PaymentRetrieveBodyWithCredentials, PaymentsAggregateResponse, + PaymentsApproveRequest, PaymentsCancelRequest, PaymentsCaptureRequest, + PaymentsCompleteAuthorizeRequest, PaymentsDynamicTaxCalculationRequest, + PaymentsDynamicTaxCalculationResponse, PaymentsExternalAuthenticationRequest, + PaymentsIncrementalAuthorizationRequest, PaymentsManualUpdateRequest, + PaymentsPostSessionTokensRequest, PaymentsPostSessionTokensResponse, + PaymentsRedirectRequest, PaymentsRedirectionResponse, PaymentsRejectRequest, + PaymentsRequest, PaymentsResponse, PaymentsResponseForm, PaymentsRetrieveRequest, + PaymentsSessionRequest, PaymentsSessionResponse, PaymentsStartRequest, + PaymentsUpdateMetadataRequest, PaymentsUpdateMetadataResponse, PgRedirectResponse, + PhoneDetails, RedirectionResponse, SessionToken, UrlDetails, VaultSessionDetails, + VerifyRequest, VerifyResponse, VgsSessionDetails, WalletData, }, }; +pub use common_types::payments::{AcceptanceType, CustomerAcceptance, OnlineMandate}; use error_stack::ResultExt; pub use hyperswitch_domain_models::router_flow_types::payments::{ Approve, Authorize, AuthorizeSessionToken, Balance, CalculateTax, Capture, CompleteAuthorize, diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs index 2e64b10c28..3a1c89a016 100644 --- a/crates/router/src/types/transformers.rs +++ b/crates/router/src/types/transformers.rs @@ -398,25 +398,7 @@ impl ForeignFrom for payments::MandateAmountDa impl ForeignFrom for hyperswitch_domain_models::mandates::MandateData { fn foreign_from(d: payments::MandateData) -> Self { Self { - customer_acceptance: d.customer_acceptance.map(|d| { - hyperswitch_domain_models::mandates::CustomerAcceptance { - acceptance_type: match d.acceptance_type { - payments::AcceptanceType::Online => { - hyperswitch_domain_models::mandates::AcceptanceType::Online - } - payments::AcceptanceType::Offline => { - hyperswitch_domain_models::mandates::AcceptanceType::Offline - } - }, - accepted_at: d.accepted_at, - online: d - .online - .map(|d| hyperswitch_domain_models::mandates::OnlineMandate { - ip_address: d.ip_address, - user_agent: d.user_agent, - }), - } - }), + customer_acceptance: d.customer_acceptance, mandate_type: d.mandate_type.map(|d| match d { payments::MandateType::MultiUse(Some(i)) => { hyperswitch_domain_models::mandates::MandateDataType::MultiUse(Some(