diff --git a/.github/workflows/CI-pr.yml b/.github/workflows/CI-pr.yml index a31d045001..4ea196e1c2 100644 --- a/.github/workflows/CI-pr.yml +++ b/.github/workflows/CI-pr.yml @@ -309,12 +309,15 @@ jobs: - name: Run cargo check with v2 features enabled shell: bash - # env: - # # Not denying warnings for now. - # # We only want to ensure successful compilation for now. - # RUSTFLAGS: "-D warnings -A clippy::todo" + env: + RUSTFLAGS: "-A warnings" + # Not denying warnings for now. + # We only want to ensure successful compilation for now. + # RUSTFLAGS: "-D warnings -A clippy::todo" run: just check_v2 - name: Run cargo check enabling only the release and v2 features shell: bash + env: + RUSTFLAGS: "-A warnings" run: cargo check --no-default-features --features "release,v2" diff --git a/crates/diesel_models/src/enums.rs b/crates/diesel_models/src/enums.rs index 68809d8d2f..77d167402e 100644 --- a/crates/diesel_models/src/enums.rs +++ b/crates/diesel_models/src/enums.rs @@ -172,7 +172,7 @@ common_utils::impl_to_sql_from_sql_json!(MandateDataType); #[derive(Clone, Debug, serde::Serialize, serde::Deserialize, PartialEq, Eq)] pub struct MandateAmountData { - pub amount: i64, + pub amount: common_utils::types::MinorUnit, pub currency: Currency, pub start_date: Option, pub end_date: Option, diff --git a/crates/diesel_models/src/kv.rs b/crates/diesel_models/src/kv.rs index c8940c4c6b..1cf7fc9d81 100644 --- a/crates/diesel_models/src/kv.rs +++ b/crates/diesel_models/src/kv.rs @@ -1,6 +1,8 @@ use error_stack::ResultExt; use serde::{Deserialize, Serialize}; +#[cfg(all(feature = "v2", feature = "payment_v2"))] +use crate::payment_attempt::PaymentAttemptUpdateInternal; use crate::{ address::{Address, AddressNew, AddressUpdateInternal}, customers::{Customer, CustomerNew, CustomerUpdateInternal}, @@ -109,9 +111,19 @@ impl DBOperation { Updateable::PaymentIntentUpdate(a) => { DBResult::PaymentIntent(Box::new(a.orig.update(conn, a.update_data).await?)) } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] Updateable::PaymentAttemptUpdate(a) => DBResult::PaymentAttempt(Box::new( a.orig.update_with_attempt_id(conn, a.update_data).await?, )), + #[cfg(all(feature = "v2", feature = "payment_v2"))] + Updateable::PaymentAttemptUpdate(a) => DBResult::PaymentAttempt(Box::new( + a.orig + .update_with_attempt_id( + conn, + PaymentAttemptUpdateInternal::from(a.update_data), + ) + .await?, + )), Updateable::RefundUpdate(a) => { DBResult::Refund(Box::new(a.orig.update(conn, a.update_data).await?)) } diff --git a/crates/diesel_models/src/payment_attempt.rs b/crates/diesel_models/src/payment_attempt.rs index 152037d55f..63ce905f65 100644 --- a/crates/diesel_models/src/payment_attempt.rs +++ b/crates/diesel_models/src/payment_attempt.rs @@ -19,14 +19,14 @@ pub struct PaymentAttempt { pub merchant_id: id_type::MerchantId, pub attempt_id: String, pub status: storage_enums::AttemptStatus, - pub amount: i64, + pub amount: MinorUnit, pub currency: Option, pub save_to_locker: Option, pub connector: Option, pub error_message: Option, - pub offer_amount: Option, - pub surcharge_amount: Option, - pub tax_amount: Option, + pub offer_amount: Option, + pub surcharge_amount: Option, + pub tax_amount: Option, pub payment_method_id: Option, pub payment_method: Option, pub connector_transaction_id: Option, @@ -42,7 +42,7 @@ pub struct PaymentAttempt { #[serde(default, with = "common_utils::custom_serde::iso8601::option")] pub last_synced: Option, pub cancellation_reason: Option, - pub amount_to_capture: Option, + pub amount_to_capture: Option, pub mandate_id: Option, pub browser_info: Option, pub error_code: Option, @@ -60,14 +60,14 @@ pub struct PaymentAttempt { pub multiple_capture_count: Option, // reference to the payment at connector side pub connector_response_reference_id: Option, - pub amount_capturable: i64, + pub amount_capturable: MinorUnit, pub updated_by: String, pub merchant_connector_id: Option, pub authentication_data: Option, pub encoded_data: Option, pub unified_code: Option, pub unified_message: Option, - pub net_amount: Option, + pub net_amount: Option, pub external_three_ds_authentication_attempted: Option, pub authentication_connector: Option, pub authentication_id: Option, @@ -95,14 +95,14 @@ pub struct PaymentAttempt { pub merchant_id: id_type::MerchantId, pub attempt_id: String, pub status: storage_enums::AttemptStatus, - pub amount: i64, + pub amount: MinorUnit, pub currency: Option, pub save_to_locker: Option, pub connector: Option, pub error_message: Option, - pub offer_amount: Option, - pub surcharge_amount: Option, - pub tax_amount: Option, + pub offer_amount: Option, + pub surcharge_amount: Option, + pub tax_amount: Option, pub payment_method_id: Option, pub payment_method: Option, pub connector_transaction_id: Option, @@ -118,7 +118,7 @@ pub struct PaymentAttempt { #[serde(default, with = "common_utils::custom_serde::iso8601::option")] pub last_synced: Option, pub cancellation_reason: Option, - pub amount_to_capture: Option, + pub amount_to_capture: Option, pub mandate_id: Option, pub browser_info: Option, pub error_code: Option, @@ -136,14 +136,14 @@ pub struct PaymentAttempt { pub multiple_capture_count: Option, // reference to the payment at connector side pub connector_response_reference_id: Option, - pub amount_capturable: i64, + pub amount_capturable: MinorUnit, pub updated_by: String, pub merchant_connector_id: Option, pub authentication_data: Option, pub encoded_data: Option, pub unified_code: Option, pub unified_message: Option, - pub net_amount: Option, + pub net_amount: Option, pub external_three_ds_authentication_attempted: Option, pub authentication_connector: Option, pub authentication_id: Option, @@ -162,22 +162,13 @@ pub struct PaymentAttempt { } impl PaymentAttempt { - pub fn get_or_calculate_net_amount(&self) -> i64 { - let shipping_cost = self - .shipping_cost - .unwrap_or(MinorUnit::new(0)) - .get_amount_as_i64(); - let order_tax_amount = self - .order_tax_amount - .unwrap_or(MinorUnit::new(0)) - .get_amount_as_i64(); - + pub fn get_or_calculate_net_amount(&self) -> MinorUnit { self.net_amount.unwrap_or( self.amount - + self.surcharge_amount.unwrap_or(0) - + self.tax_amount.unwrap_or(0) - + shipping_cost - + order_tax_amount, + + self.surcharge_amount.unwrap_or(MinorUnit::new(0)) + + self.tax_amount.unwrap_or(MinorUnit::new(0)) + + self.shipping_cost.unwrap_or(MinorUnit::new(0)) + + self.order_tax_amount.unwrap_or(MinorUnit::new(0)), ) } } @@ -197,15 +188,15 @@ pub struct PaymentAttemptNew { pub merchant_id: id_type::MerchantId, pub attempt_id: String, pub status: storage_enums::AttemptStatus, - pub amount: i64, + pub amount: MinorUnit, pub currency: Option, // pub auto_capture: Option, pub save_to_locker: Option, pub connector: Option, pub error_message: Option, - pub offer_amount: Option, - pub surcharge_amount: Option, - pub tax_amount: Option, + pub offer_amount: Option, + pub surcharge_amount: Option, + pub tax_amount: Option, pub payment_method_id: Option, pub payment_method: Option, pub capture_method: Option, @@ -220,7 +211,7 @@ pub struct PaymentAttemptNew { #[serde(default, with = "common_utils::custom_serde::iso8601::option")] pub last_synced: Option, pub cancellation_reason: Option, - pub amount_to_capture: Option, + pub amount_to_capture: Option, pub mandate_id: Option, pub browser_info: Option, pub payment_token: Option, @@ -236,14 +227,14 @@ pub struct PaymentAttemptNew { pub error_reason: Option, pub connector_response_reference_id: Option, pub multiple_capture_count: Option, - pub amount_capturable: i64, + pub amount_capturable: MinorUnit, pub updated_by: String, pub merchant_connector_id: Option, pub authentication_data: Option, pub encoded_data: Option, pub unified_code: Option, pub unified_message: Option, - pub net_amount: Option, + pub net_amount: Option, pub external_three_ds_authentication_attempted: Option, pub authentication_connector: Option, pub authentication_id: Option, @@ -263,19 +254,14 @@ pub struct PaymentAttemptNew { impl PaymentAttemptNew { /// returns amount + surcharge_amount + tax_amount (surcharge) + shipping_cost + order_tax_amount - pub fn calculate_net_amount(&self) -> i64 { - let shipping_cost = self - .shipping_cost - .unwrap_or(MinorUnit::new(0)) - .get_amount_as_i64(); - + pub fn calculate_net_amount(&self) -> MinorUnit { self.amount - + self.surcharge_amount.unwrap_or(0) - + self.tax_amount.unwrap_or(0) - + shipping_cost + + self.surcharge_amount.unwrap_or(MinorUnit::new(0)) + + self.tax_amount.unwrap_or(MinorUnit::new(0)) + + self.shipping_cost.unwrap_or(MinorUnit::new(0)) } - pub fn get_or_calculate_net_amount(&self) -> i64 { + pub fn get_or_calculate_net_amount(&self) -> MinorUnit { self.net_amount .unwrap_or_else(|| self.calculate_net_amount()) } @@ -290,7 +276,7 @@ impl PaymentAttemptNew { #[derive(Debug, Clone, Serialize, Deserialize)] pub enum PaymentAttemptUpdate { Update { - amount: i64, + amount: MinorUnit, currency: storage_enums::Currency, status: storage_enums::AttemptStatus, authentication_type: Option, @@ -300,10 +286,10 @@ pub enum PaymentAttemptUpdate { payment_method_type: Option, payment_experience: Option, business_sub_label: Option, - amount_to_capture: Option, + amount_to_capture: Option, capture_method: Option, - surcharge_amount: Option, - tax_amount: Option, + surcharge_amount: Option, + tax_amount: Option, fingerprint_id: Option, payment_method_billing_address_id: Option, updated_by: String, @@ -312,9 +298,9 @@ pub enum PaymentAttemptUpdate { payment_token: Option, connector: Option, straight_through_algorithm: Option, - amount_capturable: Option, - surcharge_amount: Option, - tax_amount: Option, + amount_capturable: Option, + surcharge_amount: Option, + tax_amount: Option, updated_by: String, merchant_connector_id: Option, }, @@ -323,7 +309,7 @@ pub enum PaymentAttemptUpdate { updated_by: String, }, ConfirmUpdate { - amount: i64, + amount: MinorUnit, currency: storage_enums::Currency, status: storage_enums::AttemptStatus, authentication_type: Option, @@ -339,9 +325,9 @@ pub enum PaymentAttemptUpdate { straight_through_algorithm: Option, error_code: Option>, error_message: Option>, - amount_capturable: Option, - surcharge_amount: Option, - tax_amount: Option, + amount_capturable: Option, + surcharge_amount: Option, + tax_amount: Option, fingerprint_id: Option, updated_by: String, merchant_connector_id: Option, @@ -390,7 +376,7 @@ pub enum PaymentAttemptUpdate { error_message: Option>, error_reason: Option>, connector_response_reference_id: Option, - amount_capturable: Option, + amount_capturable: Option, updated_by: String, authentication_data: Option, encoded_data: Option, @@ -420,7 +406,7 @@ pub enum PaymentAttemptUpdate { error_code: Option>, error_message: Option>, error_reason: Option>, - amount_capturable: Option, + amount_capturable: Option, updated_by: String, unified_code: Option>, unified_message: Option>, @@ -429,13 +415,13 @@ pub enum PaymentAttemptUpdate { authentication_type: Option, }, CaptureUpdate { - amount_to_capture: Option, + amount_to_capture: Option, multiple_capture_count: Option, updated_by: String, }, AmountToCaptureUpdate { status: storage_enums::AttemptStatus, - amount_capturable: i64, + amount_capturable: MinorUnit, updated_by: String, }, PreprocessingUpdate { @@ -456,8 +442,8 @@ pub enum PaymentAttemptUpdate { updated_by: String, }, IncrementalAuthorizationAmountUpdate { - amount: i64, - amount_capturable: i64, + amount: MinorUnit, + amount_capturable: MinorUnit, }, AuthenticationUpdate { status: storage_enums::AttemptStatus, @@ -481,82 +467,78 @@ pub enum PaymentAttemptUpdate { #[derive(Clone, Debug, AsChangeset, router_derive::DebugAsDisplay)] #[diesel(table_name = payment_attempt)] pub struct PaymentAttemptUpdateInternal { - amount: Option, - net_amount: Option, - currency: Option, - status: Option, - connector_transaction_id: Option, - amount_to_capture: Option, - connector: Option>, - authentication_type: Option, - payment_method: Option, - error_message: Option>, - payment_method_id: Option, - cancellation_reason: Option, - modified_at: PrimitiveDateTime, - mandate_id: Option, - browser_info: Option, - payment_token: Option, - error_code: Option>, - connector_metadata: Option, - payment_method_data: Option, - payment_method_type: Option, - payment_experience: Option, - business_sub_label: Option, - straight_through_algorithm: Option, - preprocessing_step_id: Option, - error_reason: Option>, - capture_method: Option, - connector_response_reference_id: Option, - multiple_capture_count: Option, - surcharge_amount: Option, - tax_amount: Option, - amount_capturable: Option, - updated_by: String, - merchant_connector_id: Option>, - authentication_data: Option, - encoded_data: Option, - unified_code: Option>, - unified_message: Option>, - external_three_ds_authentication_attempted: Option, - authentication_connector: Option, - authentication_id: Option, - fingerprint_id: Option, - payment_method_billing_address_id: Option, - charge_id: Option, - client_source: Option, - client_version: Option, - customer_acceptance: Option, - card_network: Option, - shipping_cost: Option, - order_tax_amount: Option, + pub amount: Option, + pub net_amount: Option, + pub currency: Option, + pub status: Option, + pub connector_transaction_id: Option, + pub amount_to_capture: Option, + pub connector: Option>, + pub authentication_type: Option, + pub payment_method: Option, + pub error_message: Option>, + pub payment_method_id: Option, + pub cancellation_reason: Option, + pub modified_at: PrimitiveDateTime, + pub mandate_id: Option, + pub browser_info: Option, + pub payment_token: Option, + pub error_code: Option>, + pub connector_metadata: Option, + pub payment_method_data: Option, + pub payment_method_type: Option, + pub payment_experience: Option, + pub business_sub_label: Option, + pub straight_through_algorithm: Option, + pub preprocessing_step_id: Option, + pub error_reason: Option>, + pub capture_method: Option, + pub connector_response_reference_id: Option, + pub multiple_capture_count: Option, + pub surcharge_amount: Option, + pub tax_amount: Option, + pub amount_capturable: Option, + pub updated_by: String, + pub merchant_connector_id: Option>, + pub authentication_data: Option, + pub encoded_data: Option, + pub unified_code: Option>, + pub unified_message: Option>, + pub external_three_ds_authentication_attempted: Option, + pub authentication_connector: Option, + pub authentication_id: Option, + pub fingerprint_id: Option, + pub payment_method_billing_address_id: Option, + pub charge_id: Option, + pub client_source: Option, + pub client_version: Option, + pub customer_acceptance: Option, + pub card_network: Option, + pub shipping_cost: Option, + pub order_tax_amount: Option, } impl PaymentAttemptUpdateInternal { pub fn populate_derived_fields(self, source: &PaymentAttempt) -> Self { let mut update_internal = self; - let shipping_cost = update_internal - .shipping_cost - .or(source.shipping_cost) - .unwrap_or(MinorUnit::new(0)) - .get_amount_as_i64(); - let order_tax_amount = update_internal - .order_tax_amount - .or(source.order_tax_amount) - .unwrap_or(MinorUnit::new(0)) - .get_amount_as_i64(); update_internal.net_amount = Some( update_internal.amount.unwrap_or(source.amount) + update_internal .surcharge_amount .or(source.surcharge_amount) - .unwrap_or(0) + .unwrap_or(MinorUnit::new(0)) + update_internal .tax_amount .or(source.tax_amount) - .unwrap_or(0) - + shipping_cost - + order_tax_amount, + .unwrap_or(MinorUnit::new(0)) + + update_internal + .shipping_cost + .or(source.shipping_cost) + .unwrap_or(MinorUnit::new(0)) + + update_internal + .order_tax_amount + .or(source.order_tax_amount) + .unwrap_or(MinorUnit::new(0)), ); update_internal.card_network = update_internal .payment_method_data diff --git a/crates/diesel_models/src/query/payment_attempt.rs b/crates/diesel_models/src/query/payment_attempt.rs index a9d44bca88..fa80b0990d 100644 --- a/crates/diesel_models/src/query/payment_attempt.rs +++ b/crates/diesel_models/src/query/payment_attempt.rs @@ -29,6 +29,7 @@ impl PaymentAttemptNew { } impl PaymentAttempt { + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] pub async fn update_with_attempt_id( self, conn: &PgPooledConn, @@ -56,6 +57,34 @@ impl PaymentAttempt { } } + #[cfg(all(feature = "v2", feature = "payment_v2"))] + pub async fn update_with_attempt_id( + self, + conn: &PgPooledConn, + payment_attempt: PaymentAttemptUpdateInternal, + ) -> StorageResult { + match generics::generic_update_with_unique_predicate_get_result::< + ::Table, + _, + _, + _, + >( + conn, + dsl::attempt_id + .eq(self.attempt_id.to_owned()) + .and(dsl::merchant_id.eq(self.merchant_id.to_owned())), + payment_attempt.populate_derived_fields(&self), + ) + .await + { + Err(error) => match error.current_context() { + DatabaseError::NoFieldsToUpdate => Ok(self), + _ => Err(error), + }, + result => result, + } + } + pub async fn find_optional_by_payment_id_merchant_id( conn: &PgPooledConn, payment_id: &common_utils::id_type::PaymentId, diff --git a/crates/diesel_models/src/user/sample_data.rs b/crates/diesel_models/src/user/sample_data.rs index f4c8cf30fa..ddcf6352c5 100644 --- a/crates/diesel_models/src/user/sample_data.rs +++ b/crates/diesel_models/src/user/sample_data.rs @@ -24,14 +24,14 @@ pub struct PaymentAttemptBatchNew { pub merchant_id: common_utils::id_type::MerchantId, pub attempt_id: String, pub status: AttemptStatus, - pub amount: i64, + pub amount: MinorUnit, pub currency: Option, pub save_to_locker: Option, pub connector: Option, pub error_message: Option, - pub offer_amount: Option, - pub surcharge_amount: Option, - pub tax_amount: Option, + pub offer_amount: Option, + pub surcharge_amount: Option, + pub tax_amount: Option, pub payment_method_id: Option, pub payment_method: Option, pub capture_method: Option, @@ -46,7 +46,7 @@ pub struct PaymentAttemptBatchNew { #[serde(default, with = "common_utils::custom_serde::iso8601::option")] pub last_synced: Option, pub cancellation_reason: Option, - pub amount_to_capture: Option, + pub amount_to_capture: Option, pub mandate_id: Option, pub browser_info: Option, pub payment_token: Option, @@ -63,14 +63,14 @@ pub struct PaymentAttemptBatchNew { pub connector_response_reference_id: Option, pub connector_transaction_id: Option, pub multiple_capture_count: Option, - pub amount_capturable: i64, + pub amount_capturable: MinorUnit, pub updated_by: String, pub merchant_connector_id: Option, pub authentication_data: Option, pub encoded_data: Option, pub unified_code: Option, pub unified_message: Option, - pub net_amount: Option, + pub net_amount: Option, pub external_three_ds_authentication_attempted: Option, pub authentication_connector: Option, pub authentication_id: Option, diff --git a/crates/hyperswitch_domain_models/src/mandates.rs b/crates/hyperswitch_domain_models/src/mandates.rs index c1380fe51c..d12b041a8a 100644 --- a/crates/hyperswitch_domain_models/src/mandates.rs +++ b/crates/hyperswitch_domain_models/src/mandates.rs @@ -15,6 +15,22 @@ pub struct MandateDetails { pub update_mandate_id: Option, } +impl From for diesel_models::enums::MandateDetails { + fn from(value: MandateDetails) -> Self { + Self { + update_mandate_id: value.update_mandate_id, + } + } +} + +impl From for MandateDetails { + fn from(value: diesel_models::enums::MandateDetails) -> Self { + Self { + update_mandate_id: value.update_mandate_id, + } + } +} + #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(rename_all = "snake_case")] pub enum MandateDataType { @@ -84,6 +100,28 @@ impl From for MandateDataType { } } +impl From for diesel_models::enums::MandateDataType { + fn from(value: MandateDataType) -> Self { + match value { + MandateDataType::SingleUse(data) => Self::SingleUse(data.into()), + MandateDataType::MultiUse(None) => Self::MultiUse(None), + MandateDataType::MultiUse(Some(data)) => Self::MultiUse(Some(data.into())), + } + } +} + +impl From for MandateDataType { + fn from(value: diesel_models::enums::MandateDataType) -> Self { + use diesel_models::enums::MandateDataType as DieselMandateDataType; + + match value { + DieselMandateDataType::SingleUse(data) => Self::SingleUse(data.into()), + DieselMandateDataType::MultiUse(None) => Self::MultiUse(None), + DieselMandateDataType::MultiUse(Some(data)) => Self::MultiUse(Some(data.into())), + } + } +} + impl From for MandateAmountData { fn from(value: ApiMandateAmountData) -> Self { Self { @@ -96,6 +134,30 @@ impl From for MandateAmountData { } } +impl From for diesel_models::enums::MandateAmountData { + fn from(value: MandateAmountData) -> Self { + Self { + amount: value.amount, + currency: value.currency, + start_date: value.start_date, + end_date: value.end_date, + metadata: value.metadata, + } + } +} + +impl From for MandateAmountData { + fn from(value: diesel_models::enums::MandateAmountData) -> Self { + Self { + amount: value.amount, + currency: value.currency, + start_date: value.start_date, + end_date: value.end_date, + metadata: value.metadata, + } + } +} + impl From for MandateData { fn from(value: ApiMandateData) -> Self { Self { diff --git a/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs b/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs index b9cfba86d4..24a79e2905 100644 --- a/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs +++ b/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs @@ -1,35 +1,49 @@ use api_models::enums::Connector; use common_enums as storage_enums; use common_utils::{ - encryption::Encryption, errors::{CustomResult, ValidationError}, - id_type, pii, type_name, + id_type, pii, types::{ keymanager::{self, KeyManagerState}, MinorUnit, }, }; +use diesel_models::{ + PaymentAttempt as DieselPaymentAttempt, PaymentAttemptNew as DieselPaymentAttemptNew, +}; use error_stack::ResultExt; -use masking::PeekInterface; +use masking::Secret; use serde::{Deserialize, Serialize}; use time::PrimitiveDateTime; use super::PaymentIntent; +#[cfg(all(feature = "v2", feature = "payment_v2"))] +use crate::merchant_key_store::MerchantKeyStore; use crate::{ behaviour, errors, mandates::{MandateDataType, MandateDetails}, - type_encryption::{crypto_operation, AsyncLift, CryptoOperation}, - ForeignIDRef, RemoteStorageObject, + ForeignIDRef, }; #[async_trait::async_trait] pub trait PaymentAttemptInterface { + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn insert_payment_attempt( &self, payment_attempt: PaymentAttemptNew, storage_scheme: storage_enums::MerchantStorageScheme, ) -> error_stack::Result; + #[cfg(all(feature = "v2", feature = "payment_v2"))] + async fn insert_payment_attempt( + &self, + key_manager_state: &KeyManagerState, + merchant_key_store: &MerchantKeyStore, + payment_attempt: PaymentAttempt, + storage_scheme: storage_enums::MerchantStorageScheme, + ) -> error_stack::Result; + + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn update_payment_attempt_with_attempt_id( &self, this: PaymentAttempt, @@ -37,6 +51,17 @@ pub trait PaymentAttemptInterface { storage_scheme: storage_enums::MerchantStorageScheme, ) -> error_stack::Result; + #[cfg(all(feature = "v2", feature = "payment_v2"))] + async fn update_payment_attempt_with_attempt_id( + &self, + key_manager_state: &KeyManagerState, + merchant_key_store: &MerchantKeyStore, + this: PaymentAttempt, + payment_attempt: PaymentAttemptUpdate, + storage_scheme: storage_enums::MerchantStorageScheme, + ) -> error_stack::Result; + + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn find_payment_attempt_by_connector_transaction_id_payment_id_merchant_id( &self, connector_transaction_id: &str, @@ -45,6 +70,7 @@ pub trait PaymentAttemptInterface { storage_scheme: storage_enums::MerchantStorageScheme, ) -> error_stack::Result; + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn find_payment_attempt_last_successful_attempt_by_payment_id_merchant_id( &self, payment_id: &id_type::PaymentId, @@ -52,6 +78,7 @@ pub trait PaymentAttemptInterface { storage_scheme: storage_enums::MerchantStorageScheme, ) -> error_stack::Result; + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn find_payment_attempt_last_successful_or_partially_captured_attempt_by_payment_id_merchant_id( &self, payment_id: &id_type::PaymentId, @@ -59,6 +86,7 @@ pub trait PaymentAttemptInterface { storage_scheme: storage_enums::MerchantStorageScheme, ) -> error_stack::Result; + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn find_payment_attempt_by_merchant_id_connector_txn_id( &self, merchant_id: &id_type::MerchantId, @@ -66,6 +94,7 @@ pub trait PaymentAttemptInterface { storage_scheme: storage_enums::MerchantStorageScheme, ) -> error_stack::Result; + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn find_payment_attempt_by_payment_id_merchant_id_attempt_id( &self, payment_id: &id_type::PaymentId, @@ -74,6 +103,7 @@ pub trait PaymentAttemptInterface { storage_scheme: storage_enums::MerchantStorageScheme, ) -> error_stack::Result; + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn find_payment_attempt_by_attempt_id_merchant_id( &self, attempt_id: &str, @@ -81,6 +111,17 @@ pub trait PaymentAttemptInterface { storage_scheme: storage_enums::MerchantStorageScheme, ) -> error_stack::Result; + #[cfg(all(feature = "v2", feature = "payment_v2"))] + async fn find_payment_attempt_by_attempt_id_merchant_id( + &self, + key_manager_state: &KeyManagerState, + merchant_key_store: &MerchantKeyStore, + attempt_id: &str, + merchant_id: &id_type::MerchantId, + storage_scheme: storage_enums::MerchantStorageScheme, + ) -> error_stack::Result; + + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn find_payment_attempt_by_preprocessing_id_merchant_id( &self, preprocessing_id: &str, @@ -88,6 +129,7 @@ pub trait PaymentAttemptInterface { storage_scheme: storage_enums::MerchantStorageScheme, ) -> error_stack::Result; + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn find_attempts_by_merchant_id_payment_id( &self, merchant_id: &id_type::MerchantId, @@ -95,6 +137,7 @@ pub trait PaymentAttemptInterface { storage_scheme: storage_enums::MerchantStorageScheme, ) -> error_stack::Result, errors::StorageError>; + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn get_filters_for_payments( &self, pi: &[PaymentIntent], @@ -102,6 +145,7 @@ pub trait PaymentAttemptInterface { storage_scheme: storage_enums::MerchantStorageScheme, ) -> error_stack::Result; + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] #[allow(clippy::too_many_arguments)] async fn get_total_count_of_filtered_payment_attempts( &self, @@ -490,434 +534,1634 @@ pub enum PaymentAttemptUpdate { }, } +#[cfg(all(feature = "v2", feature = "payment_v2"))] +impl From for diesel_models::PaymentAttemptUpdateInternal { + fn from(payment_attempt_update: PaymentAttemptUpdate) -> Self { + match payment_attempt_update { + PaymentAttemptUpdate::Update { + amount, + currency, + status, + authentication_type, + payment_method, + payment_token, + payment_method_data, + payment_method_type, + payment_experience, + business_sub_label, + amount_to_capture, + capture_method, + surcharge_amount, + tax_amount, + fingerprint_id, + updated_by, + payment_method_billing_address_id, + } => Self { + amount: Some(amount), + currency: Some(currency), + status: Some(status), + authentication_type, + payment_method, + payment_token, + modified_at: common_utils::date_time::now(), + payment_method_data, + payment_method_type, + payment_experience, + business_sub_label, + amount_to_capture, + capture_method, + surcharge_amount, + tax_amount, + fingerprint_id, + payment_method_billing_address_id, + updated_by, + net_amount: None, + connector_transaction_id: None, + connector: None, + error_message: None, + payment_method_id: None, + cancellation_reason: None, + mandate_id: None, + browser_info: None, + error_code: None, + connector_metadata: None, + straight_through_algorithm: None, + preprocessing_step_id: None, + error_reason: None, + connector_response_reference_id: None, + multiple_capture_count: None, + amount_capturable: None, + merchant_connector_id: None, + authentication_data: None, + encoded_data: None, + unified_code: None, + unified_message: None, + external_three_ds_authentication_attempted: None, + authentication_connector: None, + authentication_id: None, + charge_id: None, + client_source: None, + client_version: None, + customer_acceptance: None, + card_network: None, + shipping_cost: None, + order_tax_amount: None, + }, + PaymentAttemptUpdate::AuthenticationTypeUpdate { + authentication_type, + updated_by, + } => Self { + authentication_type: Some(authentication_type), + modified_at: common_utils::date_time::now(), + updated_by, + amount: None, + net_amount: None, + currency: None, + status: None, + connector_transaction_id: None, + amount_to_capture: None, + connector: None, + payment_method: None, + error_message: None, + payment_method_id: None, + cancellation_reason: None, + mandate_id: None, + browser_info: None, + payment_token: None, + error_code: None, + connector_metadata: None, + payment_method_data: None, + payment_method_type: None, + payment_experience: None, + business_sub_label: None, + straight_through_algorithm: None, + preprocessing_step_id: None, + error_reason: None, + capture_method: None, + connector_response_reference_id: None, + multiple_capture_count: None, + surcharge_amount: None, + tax_amount: None, + amount_capturable: None, + merchant_connector_id: None, + authentication_data: None, + encoded_data: None, + unified_code: None, + unified_message: None, + external_three_ds_authentication_attempted: None, + authentication_connector: None, + authentication_id: None, + fingerprint_id: None, + payment_method_billing_address_id: None, + charge_id: None, + client_source: None, + client_version: None, + customer_acceptance: None, + card_network: None, + shipping_cost: None, + order_tax_amount: None, + }, + PaymentAttemptUpdate::ConfirmUpdate { + amount, + currency, + authentication_type, + capture_method, + status, + payment_method, + browser_info, + connector, + payment_token, + payment_method_data, + payment_method_type, + payment_experience, + business_sub_label, + straight_through_algorithm, + error_code, + error_message, + amount_capturable, + updated_by, + merchant_connector_id, + surcharge_amount, + tax_amount, + external_three_ds_authentication_attempted, + authentication_connector, + authentication_id, + payment_method_billing_address_id, + fingerprint_id, + payment_method_id, + client_source, + client_version, + customer_acceptance, + shipping_cost, + order_tax_amount, + } => Self { + amount: Some(amount), + currency: Some(currency), + authentication_type, + status: Some(status), + payment_method, + modified_at: common_utils::date_time::now(), + browser_info, + connector: connector.map(Some), + payment_token, + payment_method_data, + payment_method_type, + payment_experience, + business_sub_label, + straight_through_algorithm, + error_code, + error_message, + amount_capturable, + updated_by, + merchant_connector_id: merchant_connector_id.map(Some), + surcharge_amount, + tax_amount, + external_three_ds_authentication_attempted, + authentication_connector, + authentication_id, + payment_method_billing_address_id, + fingerprint_id, + payment_method_id, + capture_method, + client_source, + client_version, + customer_acceptance, + net_amount: None, + connector_transaction_id: None, + amount_to_capture: None, + cancellation_reason: None, + mandate_id: None, + connector_metadata: None, + preprocessing_step_id: None, + error_reason: None, + connector_response_reference_id: None, + multiple_capture_count: None, + authentication_data: None, + encoded_data: None, + unified_code: None, + unified_message: None, + charge_id: None, + card_network: None, + shipping_cost, + order_tax_amount, + }, + PaymentAttemptUpdate::VoidUpdate { + status, + cancellation_reason, + updated_by, + } => Self { + status: Some(status), + cancellation_reason, + modified_at: common_utils::date_time::now(), + updated_by, + amount: None, + net_amount: None, + currency: None, + connector_transaction_id: None, + amount_to_capture: None, + connector: None, + authentication_type: None, + payment_method: None, + error_message: None, + payment_method_id: None, + mandate_id: None, + browser_info: None, + payment_token: None, + error_code: None, + connector_metadata: None, + payment_method_data: None, + payment_method_type: None, + payment_experience: None, + business_sub_label: None, + straight_through_algorithm: None, + preprocessing_step_id: None, + error_reason: None, + capture_method: None, + connector_response_reference_id: None, + multiple_capture_count: None, + surcharge_amount: None, + tax_amount: None, + amount_capturable: None, + merchant_connector_id: None, + authentication_data: None, + encoded_data: None, + unified_code: None, + unified_message: None, + external_three_ds_authentication_attempted: None, + authentication_connector: None, + authentication_id: None, + fingerprint_id: None, + payment_method_billing_address_id: None, + charge_id: None, + client_source: None, + client_version: None, + customer_acceptance: None, + card_network: None, + shipping_cost: None, + order_tax_amount: None, + }, + PaymentAttemptUpdate::RejectUpdate { + status, + error_code, + error_message, + updated_by, + } => Self { + status: Some(status), + modified_at: common_utils::date_time::now(), + error_code, + error_message, + updated_by, + amount: None, + net_amount: None, + currency: None, + connector_transaction_id: None, + amount_to_capture: None, + connector: None, + authentication_type: None, + payment_method: None, + payment_method_id: None, + cancellation_reason: None, + mandate_id: None, + browser_info: None, + payment_token: None, + connector_metadata: None, + payment_method_data: None, + payment_method_type: None, + payment_experience: None, + business_sub_label: None, + straight_through_algorithm: None, + preprocessing_step_id: None, + error_reason: None, + capture_method: None, + connector_response_reference_id: None, + multiple_capture_count: None, + surcharge_amount: None, + tax_amount: None, + amount_capturable: None, + merchant_connector_id: None, + authentication_data: None, + encoded_data: None, + unified_code: None, + unified_message: None, + external_three_ds_authentication_attempted: None, + authentication_connector: None, + authentication_id: None, + fingerprint_id: None, + payment_method_billing_address_id: None, + charge_id: None, + client_source: None, + client_version: None, + customer_acceptance: None, + card_network: None, + shipping_cost: None, + order_tax_amount: None, + }, + PaymentAttemptUpdate::BlocklistUpdate { + status, + error_code, + error_message, + updated_by, + } => Self { + status: Some(status), + modified_at: common_utils::date_time::now(), + error_code, + connector: Some(None), + error_message, + updated_by, + merchant_connector_id: Some(None), + amount: None, + net_amount: None, + currency: None, + connector_transaction_id: None, + amount_to_capture: None, + authentication_type: None, + payment_method: None, + payment_method_id: None, + cancellation_reason: None, + mandate_id: None, + browser_info: None, + payment_token: None, + connector_metadata: None, + payment_method_data: None, + payment_method_type: None, + payment_experience: None, + business_sub_label: None, + straight_through_algorithm: None, + preprocessing_step_id: None, + error_reason: None, + capture_method: None, + connector_response_reference_id: None, + multiple_capture_count: None, + surcharge_amount: None, + tax_amount: None, + amount_capturable: None, + authentication_data: None, + encoded_data: None, + unified_code: None, + unified_message: None, + external_three_ds_authentication_attempted: None, + authentication_connector: None, + authentication_id: None, + fingerprint_id: None, + payment_method_billing_address_id: None, + charge_id: None, + client_source: None, + client_version: None, + customer_acceptance: None, + card_network: None, + shipping_cost: None, + order_tax_amount: None, + }, + PaymentAttemptUpdate::PaymentMethodDetailsUpdate { + payment_method_id, + updated_by, + } => Self { + payment_method_id, + modified_at: common_utils::date_time::now(), + updated_by, + amount: None, + net_amount: None, + currency: None, + status: None, + connector_transaction_id: None, + amount_to_capture: None, + connector: None, + authentication_type: None, + payment_method: None, + error_message: None, + cancellation_reason: None, + mandate_id: None, + browser_info: None, + payment_token: None, + error_code: None, + connector_metadata: None, + payment_method_data: None, + payment_method_type: None, + payment_experience: None, + business_sub_label: None, + straight_through_algorithm: None, + preprocessing_step_id: None, + error_reason: None, + capture_method: None, + connector_response_reference_id: None, + multiple_capture_count: None, + surcharge_amount: None, + tax_amount: None, + amount_capturable: None, + merchant_connector_id: None, + authentication_data: None, + encoded_data: None, + unified_code: None, + unified_message: None, + external_three_ds_authentication_attempted: None, + authentication_connector: None, + authentication_id: None, + fingerprint_id: None, + payment_method_billing_address_id: None, + charge_id: None, + client_source: None, + client_version: None, + customer_acceptance: None, + card_network: None, + shipping_cost: None, + order_tax_amount: None, + }, + PaymentAttemptUpdate::ResponseUpdate { + status, + connector, + connector_transaction_id, + authentication_type, + payment_method_id, + mandate_id, + connector_metadata, + payment_token, + error_code, + error_message, + error_reason, + connector_response_reference_id, + amount_capturable, + updated_by, + authentication_data, + encoded_data, + unified_code, + unified_message, + payment_method_data, + charge_id, + } => Self { + status: Some(status), + connector: connector.map(Some), + connector_transaction_id, + authentication_type, + payment_method_id, + modified_at: common_utils::date_time::now(), + mandate_id, + connector_metadata, + error_code, + error_message, + payment_token, + error_reason, + connector_response_reference_id, + amount_capturable, + updated_by, + authentication_data, + encoded_data, + unified_code, + unified_message, + payment_method_data, + charge_id, + amount: None, + net_amount: None, + currency: None, + amount_to_capture: None, + payment_method: None, + cancellation_reason: None, + browser_info: None, + payment_method_type: None, + payment_experience: None, + business_sub_label: None, + straight_through_algorithm: None, + preprocessing_step_id: None, + capture_method: None, + multiple_capture_count: None, + surcharge_amount: None, + tax_amount: None, + merchant_connector_id: None, + external_three_ds_authentication_attempted: None, + authentication_connector: None, + authentication_id: None, + fingerprint_id: None, + payment_method_billing_address_id: None, + client_source: None, + client_version: None, + customer_acceptance: None, + card_network: None, + shipping_cost: None, + order_tax_amount: None, + }, + PaymentAttemptUpdate::ErrorUpdate { + connector, + status, + error_code, + error_message, + error_reason, + amount_capturable, + updated_by, + unified_code, + unified_message, + connector_transaction_id, + payment_method_data, + authentication_type, + } => Self { + connector: connector.map(Some), + status: Some(status), + error_message, + error_code, + modified_at: common_utils::date_time::now(), + error_reason, + amount_capturable, + updated_by, + unified_code, + unified_message, + connector_transaction_id, + payment_method_data, + authentication_type, + amount: None, + net_amount: None, + currency: None, + amount_to_capture: None, + payment_method: None, + payment_method_id: None, + cancellation_reason: None, + mandate_id: None, + browser_info: None, + payment_token: None, + connector_metadata: None, + payment_method_type: None, + payment_experience: None, + business_sub_label: None, + straight_through_algorithm: None, + preprocessing_step_id: None, + capture_method: None, + connector_response_reference_id: None, + multiple_capture_count: None, + surcharge_amount: None, + tax_amount: None, + merchant_connector_id: None, + authentication_data: None, + encoded_data: None, + external_three_ds_authentication_attempted: None, + authentication_connector: None, + authentication_id: None, + fingerprint_id: None, + payment_method_billing_address_id: None, + charge_id: None, + client_source: None, + client_version: None, + customer_acceptance: None, + card_network: None, + shipping_cost: None, + order_tax_amount: None, + }, + PaymentAttemptUpdate::StatusUpdate { status, updated_by } => Self { + status: Some(status), + modified_at: common_utils::date_time::now(), + updated_by, + amount: None, + net_amount: None, + currency: None, + connector_transaction_id: None, + amount_to_capture: None, + connector: None, + authentication_type: None, + payment_method: None, + error_message: None, + payment_method_id: None, + cancellation_reason: None, + mandate_id: None, + browser_info: None, + payment_token: None, + error_code: None, + connector_metadata: None, + payment_method_data: None, + payment_method_type: None, + payment_experience: None, + business_sub_label: None, + straight_through_algorithm: None, + preprocessing_step_id: None, + error_reason: None, + capture_method: None, + connector_response_reference_id: None, + multiple_capture_count: None, + surcharge_amount: None, + tax_amount: None, + amount_capturable: None, + merchant_connector_id: None, + authentication_data: None, + encoded_data: None, + unified_code: None, + unified_message: None, + external_three_ds_authentication_attempted: None, + authentication_connector: None, + authentication_id: None, + fingerprint_id: None, + payment_method_billing_address_id: None, + charge_id: None, + client_source: None, + client_version: None, + customer_acceptance: None, + card_network: None, + shipping_cost: None, + order_tax_amount: None, + }, + PaymentAttemptUpdate::UpdateTrackers { + payment_token, + connector, + straight_through_algorithm, + amount_capturable, + surcharge_amount, + tax_amount, + updated_by, + merchant_connector_id, + } => Self { + payment_token, + modified_at: common_utils::date_time::now(), + connector: connector.map(Some), + straight_through_algorithm, + amount_capturable, + surcharge_amount, + tax_amount, + updated_by, + merchant_connector_id: merchant_connector_id.map(Some), + amount: None, + net_amount: None, + currency: None, + status: None, + connector_transaction_id: None, + amount_to_capture: None, + authentication_type: None, + payment_method: None, + error_message: None, + payment_method_id: None, + cancellation_reason: None, + mandate_id: None, + browser_info: None, + error_code: None, + connector_metadata: None, + payment_method_data: None, + payment_method_type: None, + payment_experience: None, + business_sub_label: None, + preprocessing_step_id: None, + error_reason: None, + capture_method: None, + connector_response_reference_id: None, + multiple_capture_count: None, + authentication_data: None, + encoded_data: None, + unified_code: None, + unified_message: None, + external_three_ds_authentication_attempted: None, + authentication_connector: None, + authentication_id: None, + fingerprint_id: None, + payment_method_billing_address_id: None, + charge_id: None, + client_source: None, + client_version: None, + customer_acceptance: None, + card_network: None, + shipping_cost: None, + order_tax_amount: None, + }, + PaymentAttemptUpdate::UnresolvedResponseUpdate { + status, + connector, + connector_transaction_id, + payment_method_id, + error_code, + error_message, + error_reason, + connector_response_reference_id, + updated_by, + } => Self { + status: Some(status), + connector: connector.map(Some), + connector_transaction_id, + payment_method_id, + modified_at: common_utils::date_time::now(), + error_code, + error_message, + error_reason, + connector_response_reference_id, + updated_by, + amount: None, + net_amount: None, + currency: None, + amount_to_capture: None, + authentication_type: None, + payment_method: None, + cancellation_reason: None, + mandate_id: None, + browser_info: None, + payment_token: None, + connector_metadata: None, + payment_method_data: None, + payment_method_type: None, + payment_experience: None, + business_sub_label: None, + straight_through_algorithm: None, + preprocessing_step_id: None, + capture_method: None, + multiple_capture_count: None, + surcharge_amount: None, + tax_amount: None, + amount_capturable: None, + merchant_connector_id: None, + authentication_data: None, + encoded_data: None, + unified_code: None, + unified_message: None, + external_three_ds_authentication_attempted: None, + authentication_connector: None, + authentication_id: None, + fingerprint_id: None, + payment_method_billing_address_id: None, + charge_id: None, + client_source: None, + client_version: None, + customer_acceptance: None, + card_network: None, + shipping_cost: None, + order_tax_amount: None, + }, + PaymentAttemptUpdate::PreprocessingUpdate { + status, + payment_method_id, + connector_metadata, + preprocessing_step_id, + connector_transaction_id, + connector_response_reference_id, + updated_by, + } => Self { + status: Some(status), + payment_method_id, + modified_at: common_utils::date_time::now(), + connector_metadata, + preprocessing_step_id, + connector_transaction_id, + connector_response_reference_id, + updated_by, + amount: None, + net_amount: None, + currency: None, + amount_to_capture: None, + connector: None, + authentication_type: None, + payment_method: None, + error_message: None, + cancellation_reason: None, + mandate_id: None, + browser_info: None, + payment_token: None, + error_code: None, + payment_method_data: None, + payment_method_type: None, + payment_experience: None, + business_sub_label: None, + straight_through_algorithm: None, + error_reason: None, + capture_method: None, + multiple_capture_count: None, + surcharge_amount: None, + tax_amount: None, + amount_capturable: None, + merchant_connector_id: None, + authentication_data: None, + encoded_data: None, + unified_code: None, + unified_message: None, + external_three_ds_authentication_attempted: None, + authentication_connector: None, + authentication_id: None, + fingerprint_id: None, + payment_method_billing_address_id: None, + charge_id: None, + client_source: None, + client_version: None, + customer_acceptance: None, + card_network: None, + shipping_cost: None, + order_tax_amount: None, + }, + PaymentAttemptUpdate::CaptureUpdate { + multiple_capture_count, + updated_by, + amount_to_capture, + } => Self { + multiple_capture_count, + modified_at: common_utils::date_time::now(), + updated_by, + amount_to_capture, + amount: None, + net_amount: None, + currency: None, + status: None, + connector_transaction_id: None, + connector: None, + authentication_type: None, + payment_method: None, + error_message: None, + payment_method_id: None, + cancellation_reason: None, + mandate_id: None, + browser_info: None, + payment_token: None, + error_code: None, + connector_metadata: None, + payment_method_data: None, + payment_method_type: None, + payment_experience: None, + business_sub_label: None, + straight_through_algorithm: None, + preprocessing_step_id: None, + error_reason: None, + capture_method: None, + connector_response_reference_id: None, + surcharge_amount: None, + tax_amount: None, + amount_capturable: None, + merchant_connector_id: None, + authentication_data: None, + encoded_data: None, + unified_code: None, + unified_message: None, + external_three_ds_authentication_attempted: None, + authentication_connector: None, + authentication_id: None, + fingerprint_id: None, + payment_method_billing_address_id: None, + charge_id: None, + client_source: None, + client_version: None, + customer_acceptance: None, + card_network: None, + shipping_cost: None, + order_tax_amount: None, + }, + PaymentAttemptUpdate::AmountToCaptureUpdate { + status, + amount_capturable, + updated_by, + } => Self { + status: Some(status), + modified_at: common_utils::date_time::now(), + amount_capturable: Some(amount_capturable), + updated_by, + amount: None, + net_amount: None, + currency: None, + connector_transaction_id: None, + amount_to_capture: None, + connector: None, + authentication_type: None, + payment_method: None, + error_message: None, + payment_method_id: None, + cancellation_reason: None, + mandate_id: None, + browser_info: None, + payment_token: None, + error_code: None, + connector_metadata: None, + payment_method_data: None, + payment_method_type: None, + payment_experience: None, + business_sub_label: None, + straight_through_algorithm: None, + preprocessing_step_id: None, + error_reason: None, + capture_method: None, + connector_response_reference_id: None, + multiple_capture_count: None, + surcharge_amount: None, + tax_amount: None, + merchant_connector_id: None, + authentication_data: None, + encoded_data: None, + unified_code: None, + unified_message: None, + external_three_ds_authentication_attempted: None, + authentication_connector: None, + authentication_id: None, + fingerprint_id: None, + payment_method_billing_address_id: None, + charge_id: None, + client_source: None, + client_version: None, + customer_acceptance: None, + card_network: None, + shipping_cost: None, + order_tax_amount: None, + }, + PaymentAttemptUpdate::ConnectorResponse { + authentication_data, + encoded_data, + connector_transaction_id, + connector, + updated_by, + charge_id, + } => Self { + authentication_data, + encoded_data, + connector_transaction_id, + connector: connector.map(Some), + modified_at: common_utils::date_time::now(), + updated_by, + charge_id, + amount: None, + net_amount: None, + currency: None, + status: None, + amount_to_capture: None, + authentication_type: None, + payment_method: None, + error_message: None, + payment_method_id: None, + cancellation_reason: None, + mandate_id: None, + browser_info: None, + payment_token: None, + error_code: None, + connector_metadata: None, + payment_method_data: None, + payment_method_type: None, + payment_experience: None, + business_sub_label: None, + straight_through_algorithm: None, + preprocessing_step_id: None, + error_reason: None, + capture_method: None, + connector_response_reference_id: None, + multiple_capture_count: None, + surcharge_amount: None, + tax_amount: None, + amount_capturable: None, + merchant_connector_id: None, + unified_code: None, + unified_message: None, + external_three_ds_authentication_attempted: None, + authentication_connector: None, + authentication_id: None, + fingerprint_id: None, + payment_method_billing_address_id: None, + client_source: None, + client_version: None, + customer_acceptance: None, + card_network: None, + shipping_cost: None, + order_tax_amount: None, + }, + PaymentAttemptUpdate::IncrementalAuthorizationAmountUpdate { + amount, + amount_capturable, + } => Self { + amount: Some(amount), + modified_at: common_utils::date_time::now(), + amount_capturable: Some(amount_capturable), + net_amount: None, + currency: None, + status: None, + connector_transaction_id: None, + amount_to_capture: None, + connector: None, + authentication_type: None, + payment_method: None, + error_message: None, + payment_method_id: None, + cancellation_reason: None, + mandate_id: None, + browser_info: None, + payment_token: None, + error_code: None, + connector_metadata: None, + payment_method_data: None, + payment_method_type: None, + payment_experience: None, + business_sub_label: None, + straight_through_algorithm: None, + preprocessing_step_id: None, + error_reason: None, + capture_method: None, + connector_response_reference_id: None, + multiple_capture_count: None, + surcharge_amount: None, + tax_amount: None, + updated_by: String::default(), + merchant_connector_id: None, + authentication_data: None, + encoded_data: None, + unified_code: None, + unified_message: None, + external_three_ds_authentication_attempted: None, + authentication_connector: None, + authentication_id: None, + fingerprint_id: None, + payment_method_billing_address_id: None, + charge_id: None, + client_source: None, + client_version: None, + customer_acceptance: None, + card_network: None, + shipping_cost: None, + order_tax_amount: None, + }, + PaymentAttemptUpdate::AuthenticationUpdate { + status, + external_three_ds_authentication_attempted, + authentication_connector, + authentication_id, + updated_by, + } => Self { + status: Some(status), + modified_at: common_utils::date_time::now(), + external_three_ds_authentication_attempted, + authentication_connector, + authentication_id, + updated_by, + amount: None, + net_amount: None, + currency: None, + connector_transaction_id: None, + amount_to_capture: None, + connector: None, + authentication_type: None, + payment_method: None, + error_message: None, + payment_method_id: None, + cancellation_reason: None, + mandate_id: None, + browser_info: None, + payment_token: None, + error_code: None, + connector_metadata: None, + payment_method_data: None, + payment_method_type: None, + payment_experience: None, + business_sub_label: None, + straight_through_algorithm: None, + preprocessing_step_id: None, + error_reason: None, + capture_method: None, + connector_response_reference_id: None, + multiple_capture_count: None, + surcharge_amount: None, + tax_amount: None, + amount_capturable: None, + merchant_connector_id: None, + authentication_data: None, + encoded_data: None, + unified_code: None, + unified_message: None, + fingerprint_id: None, + payment_method_billing_address_id: None, + charge_id: None, + client_source: None, + client_version: None, + customer_acceptance: None, + card_network: None, + shipping_cost: None, + order_tax_amount: None, + }, + PaymentAttemptUpdate::ManualUpdate { + status, + error_code, + error_message, + error_reason, + updated_by, + unified_code, + unified_message, + connector_transaction_id, + } => Self { + status, + error_code: error_code.map(Some), + modified_at: common_utils::date_time::now(), + error_message: error_message.map(Some), + error_reason: error_reason.map(Some), + updated_by, + unified_code: unified_code.map(Some), + unified_message: unified_message.map(Some), + amount: None, + net_amount: None, + currency: None, + connector_transaction_id, + amount_to_capture: None, + connector: None, + authentication_type: None, + payment_method: None, + payment_method_id: None, + cancellation_reason: None, + mandate_id: None, + browser_info: None, + payment_token: None, + connector_metadata: None, + payment_method_data: None, + payment_method_type: None, + payment_experience: None, + business_sub_label: None, + straight_through_algorithm: None, + preprocessing_step_id: None, + capture_method: None, + connector_response_reference_id: None, + multiple_capture_count: None, + surcharge_amount: None, + tax_amount: None, + amount_capturable: None, + merchant_connector_id: None, + authentication_data: None, + encoded_data: None, + external_three_ds_authentication_attempted: None, + authentication_connector: None, + authentication_id: None, + fingerprint_id: None, + payment_method_billing_address_id: None, + charge_id: None, + client_source: None, + client_version: None, + customer_acceptance: None, + card_network: None, + shipping_cost: None, + order_tax_amount: None, + }, + } + } +} + impl ForeignIDRef for PaymentAttempt { fn foreign_id(&self) -> String { self.attempt_id.clone() } } -use diesel_models::{ - PaymentIntent as DieselPaymentIntent, PaymentIntentNew as DieselPaymentIntentNew, -}; - -#[cfg(all(feature = "v2", feature = "payment_v2"))] -#[async_trait::async_trait] -impl behaviour::Conversion for PaymentIntent { - type DstType = DieselPaymentIntent; - type NewDstType = DieselPaymentIntentNew; - - async fn convert(self) -> CustomResult { - Ok(DieselPaymentIntent { - merchant_id: self.merchant_id, - status: self.status, - amount: self.amount, - currency: self.currency, - amount_captured: self.amount_captured, - customer_id: self.customer_id, - description: self.description, - return_url: self.return_url, - metadata: self.metadata, - statement_descriptor_name: self.statement_descriptor_name, - created_at: self.created_at, - modified_at: self.modified_at, - last_synced: self.last_synced, - setup_future_usage: self.setup_future_usage, - off_session: self.off_session, - client_secret: self.client_secret, - active_attempt_id: self.active_attempt.get_id(), - order_details: self.order_details, - allowed_payment_method_types: self.allowed_payment_method_types, - connector_metadata: self.connector_metadata, - feature_metadata: self.feature_metadata, - attempt_count: self.attempt_count, - profile_id: self.profile_id, - frm_merchant_decision: self.frm_merchant_decision, - payment_link_id: self.payment_link_id, - payment_confirm_source: self.payment_confirm_source, - updated_by: self.updated_by, - surcharge_applicable: self.surcharge_applicable, - request_incremental_authorization: self.request_incremental_authorization, - authorization_count: self.authorization_count, - session_expiry: self.session_expiry, - request_external_three_ds_authentication: self.request_external_three_ds_authentication, - charges: self.charges, - frm_metadata: self.frm_metadata, - customer_details: self.customer_details.map(Encryption::from), - billing_address: self.billing_address.map(Encryption::from), - merchant_order_reference_id: self.merchant_order_reference_id, - shipping_address: self.shipping_address.map(Encryption::from), - is_payment_processor_token_flow: self.is_payment_processor_token_flow, - capture_method: self.capture_method, - id: self.id, - authentication_type: self.authentication_type, - amount_to_capture: self.amount_to_capture, - prerouting_algorithm: self.prerouting_algorithm, - merchant_reference_id: self.merchant_reference_id, - surcharge_amount: self.surcharge_amount, - tax_on_surcharge: self.tax_on_surcharge, - organization_id: self.organization_id, - shipping_cost: self.shipping_cost, - tax_details: self.tax_details, - skip_external_tax_calculation: self.skip_external_tax_calculation, - }) - } - async fn convert_back( - state: &KeyManagerState, - storage_model: Self::DstType, - key: &masking::Secret>, - key_manager_identifier: keymanager::Identifier, - ) -> CustomResult - where - Self: Sized, - { - async { - let inner_decrypt = |inner| async { - crypto_operation( - state, - type_name!(Self::DstType), - CryptoOperation::DecryptOptional(inner), - key_manager_identifier.clone(), - key.peek(), - ) - .await - .and_then(|val| val.try_into_optionaloperation()) - }; - Ok::>(Self { - merchant_id: storage_model.merchant_id, - status: storage_model.status, - amount: storage_model.amount, - currency: storage_model.currency, - amount_captured: storage_model.amount_captured, - customer_id: storage_model.customer_id, - description: storage_model.description, - return_url: storage_model.return_url, - metadata: storage_model.metadata, - statement_descriptor_name: storage_model.statement_descriptor_name, - created_at: storage_model.created_at, - modified_at: storage_model.modified_at, - last_synced: storage_model.last_synced, - setup_future_usage: storage_model.setup_future_usage, - off_session: storage_model.off_session, - client_secret: storage_model.client_secret, - active_attempt: RemoteStorageObject::ForeignID(storage_model.active_attempt_id), - order_details: storage_model.order_details, - allowed_payment_method_types: storage_model.allowed_payment_method_types, - connector_metadata: storage_model.connector_metadata, - feature_metadata: storage_model.feature_metadata, - attempt_count: storage_model.attempt_count, - profile_id: storage_model.profile_id, - frm_merchant_decision: storage_model.frm_merchant_decision, - payment_link_id: storage_model.payment_link_id, - payment_confirm_source: storage_model.payment_confirm_source, - updated_by: storage_model.updated_by, - surcharge_applicable: storage_model.surcharge_applicable, - request_incremental_authorization: storage_model.request_incremental_authorization, - authorization_count: storage_model.authorization_count, - session_expiry: storage_model.session_expiry, - request_external_three_ds_authentication: storage_model - .request_external_three_ds_authentication, - charges: storage_model.charges, - frm_metadata: storage_model.frm_metadata, - customer_details: storage_model - .customer_details - .async_lift(inner_decrypt) - .await?, - billing_address: storage_model - .billing_address - .async_lift(inner_decrypt) - .await?, - merchant_order_reference_id: storage_model.merchant_order_reference_id, - shipping_address: storage_model - .shipping_address - .async_lift(inner_decrypt) - .await?, - is_payment_processor_token_flow: storage_model.is_payment_processor_token_flow, - capture_method: storage_model.capture_method, - id: storage_model.id, - merchant_reference_id: storage_model.merchant_reference_id, - organization_id: storage_model.organization_id, - authentication_type: storage_model.authentication_type, - amount_to_capture: storage_model.amount_to_capture, - prerouting_algorithm: storage_model.prerouting_algorithm, - surcharge_amount: storage_model.surcharge_amount, - tax_on_surcharge: storage_model.tax_on_surcharge, - shipping_cost: storage_model.shipping_cost, - tax_details: storage_model.tax_details, - skip_external_tax_calculation: storage_model.skip_external_tax_calculation, - }) - } - .await - .change_context(ValidationError::InvalidValue { - message: "Failed while decrypting payment intent".to_string(), - }) - } - - async fn construct_new(self) -> CustomResult { - Ok(DieselPaymentIntentNew { - merchant_id: self.merchant_id, - status: self.status, - amount: self.amount, - currency: self.currency, - amount_captured: self.amount_captured, - customer_id: self.customer_id, - description: self.description, - return_url: self.return_url, - metadata: self.metadata, - statement_descriptor_name: self.statement_descriptor_name, - created_at: self.created_at, - modified_at: self.modified_at, - last_synced: self.last_synced, - setup_future_usage: self.setup_future_usage, - off_session: self.off_session, - client_secret: self.client_secret, - active_attempt_id: self.active_attempt.get_id(), - order_details: self.order_details, - allowed_payment_method_types: self.allowed_payment_method_types, - connector_metadata: self.connector_metadata, - feature_metadata: self.feature_metadata, - attempt_count: self.attempt_count, - profile_id: self.profile_id, - frm_merchant_decision: self.frm_merchant_decision, - payment_link_id: self.payment_link_id, - payment_confirm_source: self.payment_confirm_source, - updated_by: self.updated_by, - surcharge_applicable: self.surcharge_applicable, - request_incremental_authorization: self.request_incremental_authorization, - authorization_count: self.authorization_count, - session_expiry: self.session_expiry, - request_external_three_ds_authentication: self.request_external_three_ds_authentication, - charges: self.charges, - frm_metadata: self.frm_metadata, - customer_details: self.customer_details.map(Encryption::from), - billing_address: self.billing_address.map(Encryption::from), - merchant_order_reference_id: self.merchant_order_reference_id, - shipping_address: self.shipping_address.map(Encryption::from), - is_payment_processor_token_flow: self.is_payment_processor_token_flow, - capture_method: self.capture_method, - id: self.id, - merchant_reference_id: self.merchant_reference_id, - authentication_type: self.authentication_type, - amount_to_capture: self.amount_to_capture, - prerouting_algorithm: self.prerouting_algorithm, - surcharge_amount: self.surcharge_amount, - tax_on_surcharge: self.tax_on_surcharge, - organization_id: self.organization_id, - shipping_cost: self.shipping_cost, - tax_details: self.tax_details, - skip_external_tax_calculation: self.skip_external_tax_calculation, - }) - } -} - #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] #[async_trait::async_trait] -impl behaviour::Conversion for PaymentIntent { - type DstType = DieselPaymentIntent; - type NewDstType = DieselPaymentIntentNew; +impl behaviour::Conversion for PaymentAttempt { + type DstType = DieselPaymentAttempt; + type NewDstType = DieselPaymentAttemptNew; async fn convert(self) -> CustomResult { - Ok(DieselPaymentIntent { + let card_network = self + .payment_method_data + .as_ref() + .and_then(|data| data.as_object()) + .and_then(|card| card.get("card")) + .and_then(|data| data.as_object()) + .and_then(|card| card.get("card_network")) + .and_then(|network| network.as_str()) + .map(|network| network.to_string()); + Ok(DieselPaymentAttempt { payment_id: self.payment_id, merchant_id: self.merchant_id, + attempt_id: self.attempt_id, status: self.status, amount: self.amount, currency: self.currency, - amount_captured: self.amount_captured, - customer_id: self.customer_id, - description: self.description, - return_url: self.return_url, - metadata: self.metadata, - connector_id: self.connector_id, - shipping_address_id: self.shipping_address_id, - billing_address_id: self.billing_address_id, - statement_descriptor_name: self.statement_descriptor_name, - statement_descriptor_suffix: self.statement_descriptor_suffix, + save_to_locker: self.save_to_locker, + connector: self.connector, + error_message: self.error_message, + offer_amount: self.offer_amount, + surcharge_amount: self.surcharge_amount, + tax_amount: self.tax_amount, + payment_method_id: self.payment_method_id, + payment_method: self.payment_method, + connector_transaction_id: self.connector_transaction_id, + capture_method: self.capture_method, + capture_on: self.capture_on, + confirm: self.confirm, + authentication_type: self.authentication_type, created_at: self.created_at, modified_at: self.modified_at, last_synced: self.last_synced, - setup_future_usage: self.setup_future_usage, - off_session: self.off_session, - client_secret: self.client_secret, - active_attempt_id: self.active_attempt.get_id(), - business_country: self.business_country, - business_label: self.business_label, - order_details: self.order_details, - allowed_payment_method_types: self.allowed_payment_method_types, + cancellation_reason: self.cancellation_reason, + amount_to_capture: self.amount_to_capture, + mandate_id: self.mandate_id, + browser_info: self.browser_info, + error_code: self.error_code, + payment_token: self.payment_token, connector_metadata: self.connector_metadata, - feature_metadata: self.feature_metadata, - attempt_count: self.attempt_count, - profile_id: self.profile_id, - merchant_decision: self.merchant_decision, - payment_link_id: self.payment_link_id, - payment_confirm_source: self.payment_confirm_source, + payment_experience: self.payment_experience, + payment_method_type: self.payment_method_type, + payment_method_data: self.payment_method_data, + business_sub_label: self.business_sub_label, + straight_through_algorithm: self.straight_through_algorithm, + preprocessing_step_id: self.preprocessing_step_id, + mandate_details: self.mandate_details.map(Into::into), + error_reason: self.error_reason, + multiple_capture_count: self.multiple_capture_count, + connector_response_reference_id: self.connector_response_reference_id, + amount_capturable: self.amount_capturable, updated_by: self.updated_by, - surcharge_applicable: self.surcharge_applicable, - request_incremental_authorization: self.request_incremental_authorization, - incremental_authorization_allowed: self.incremental_authorization_allowed, - authorization_count: self.authorization_count, + merchant_connector_id: self.merchant_connector_id, + authentication_data: self.authentication_data, + encoded_data: self.encoded_data, + unified_code: self.unified_code, + unified_message: self.unified_message, + net_amount: Some(self.net_amount), + external_three_ds_authentication_attempted: self + .external_three_ds_authentication_attempted, + authentication_connector: self.authentication_connector, + authentication_id: self.authentication_id, + mandate_data: self.mandate_data.map(Into::into), fingerprint_id: self.fingerprint_id, - session_expiry: self.session_expiry, - request_external_three_ds_authentication: self.request_external_three_ds_authentication, - charges: self.charges, - frm_metadata: self.frm_metadata, - customer_details: self.customer_details.map(Encryption::from), - billing_details: self.billing_details.map(Encryption::from), - merchant_order_reference_id: self.merchant_order_reference_id, - shipping_details: self.shipping_details.map(Encryption::from), - is_payment_processor_token_flow: self.is_payment_processor_token_flow, + payment_method_billing_address_id: self.payment_method_billing_address_id, + charge_id: self.charge_id, + client_source: self.client_source, + client_version: self.client_version, + customer_acceptance: self.customer_acceptance, + profile_id: self.profile_id, organization_id: self.organization_id, + card_network, + order_tax_amount: self.order_tax_amount, shipping_cost: self.shipping_cost, - tax_details: self.tax_details, - skip_external_tax_calculation: self.skip_external_tax_calculation, }) } async fn convert_back( - state: &KeyManagerState, + _state: &KeyManagerState, storage_model: Self::DstType, - key: &masking::Secret>, - key_manager_identifier: keymanager::Identifier, + _key: &Secret>, + _key_manager_identifier: keymanager::Identifier, ) -> CustomResult where Self: Sized, { async { - let inner_decrypt = |inner| async { - crypto_operation( - state, - type_name!(Self::DstType), - CryptoOperation::DecryptOptional(inner), - key_manager_identifier.clone(), - key.peek(), - ) - .await - .and_then(|val| val.try_into_optionaloperation()) - }; + let net_amount = storage_model.get_or_calculate_net_amount(); Ok::>(Self { payment_id: storage_model.payment_id, merchant_id: storage_model.merchant_id, + attempt_id: storage_model.attempt_id, status: storage_model.status, amount: storage_model.amount, + net_amount, currency: storage_model.currency, - amount_captured: storage_model.amount_captured, - customer_id: storage_model.customer_id, - description: storage_model.description, - return_url: storage_model.return_url, - metadata: storage_model.metadata, - connector_id: storage_model.connector_id, - shipping_address_id: storage_model.shipping_address_id, - billing_address_id: storage_model.billing_address_id, - statement_descriptor_name: storage_model.statement_descriptor_name, - statement_descriptor_suffix: storage_model.statement_descriptor_suffix, + save_to_locker: storage_model.save_to_locker, + connector: storage_model.connector, + error_message: storage_model.error_message, + offer_amount: storage_model.offer_amount, + surcharge_amount: storage_model.surcharge_amount, + tax_amount: storage_model.tax_amount, + payment_method_id: storage_model.payment_method_id, + payment_method: storage_model.payment_method, + connector_transaction_id: storage_model.connector_transaction_id, + capture_method: storage_model.capture_method, + capture_on: storage_model.capture_on, + confirm: storage_model.confirm, + authentication_type: storage_model.authentication_type, created_at: storage_model.created_at, modified_at: storage_model.modified_at, last_synced: storage_model.last_synced, - setup_future_usage: storage_model.setup_future_usage, - off_session: storage_model.off_session, - client_secret: storage_model.client_secret, - active_attempt: RemoteStorageObject::ForeignID(storage_model.active_attempt_id), - business_country: storage_model.business_country, - business_label: storage_model.business_label, - order_details: storage_model.order_details, - allowed_payment_method_types: storage_model.allowed_payment_method_types, + cancellation_reason: storage_model.cancellation_reason, + amount_to_capture: storage_model.amount_to_capture, + mandate_id: storage_model.mandate_id, + browser_info: storage_model.browser_info, + error_code: storage_model.error_code, + payment_token: storage_model.payment_token, connector_metadata: storage_model.connector_metadata, - feature_metadata: storage_model.feature_metadata, - attempt_count: storage_model.attempt_count, - profile_id: storage_model.profile_id, - merchant_decision: storage_model.merchant_decision, - payment_link_id: storage_model.payment_link_id, - payment_confirm_source: storage_model.payment_confirm_source, + payment_experience: storage_model.payment_experience, + payment_method_type: storage_model.payment_method_type, + payment_method_data: storage_model.payment_method_data, + business_sub_label: storage_model.business_sub_label, + straight_through_algorithm: storage_model.straight_through_algorithm, + preprocessing_step_id: storage_model.preprocessing_step_id, + mandate_details: storage_model.mandate_details.map(Into::into), + error_reason: storage_model.error_reason, + multiple_capture_count: storage_model.multiple_capture_count, + connector_response_reference_id: storage_model.connector_response_reference_id, + amount_capturable: storage_model.amount_capturable, updated_by: storage_model.updated_by, - surcharge_applicable: storage_model.surcharge_applicable, - request_incremental_authorization: storage_model.request_incremental_authorization, - incremental_authorization_allowed: storage_model.incremental_authorization_allowed, - authorization_count: storage_model.authorization_count, + authentication_data: storage_model.authentication_data, + encoded_data: storage_model.encoded_data, + merchant_connector_id: storage_model.merchant_connector_id, + unified_code: storage_model.unified_code, + unified_message: storage_model.unified_message, + external_three_ds_authentication_attempted: storage_model + .external_three_ds_authentication_attempted, + authentication_connector: storage_model.authentication_connector, + authentication_id: storage_model.authentication_id, + mandate_data: storage_model.mandate_data.map(Into::into), + payment_method_billing_address_id: storage_model.payment_method_billing_address_id, fingerprint_id: storage_model.fingerprint_id, - session_expiry: storage_model.session_expiry, - request_external_three_ds_authentication: storage_model - .request_external_three_ds_authentication, - charges: storage_model.charges, - frm_metadata: storage_model.frm_metadata, - shipping_cost: storage_model.shipping_cost, - tax_details: storage_model.tax_details, - customer_details: storage_model - .customer_details - .async_lift(inner_decrypt) - .await?, - billing_details: storage_model - .billing_details - .async_lift(inner_decrypt) - .await?, - merchant_order_reference_id: storage_model.merchant_order_reference_id, - shipping_details: storage_model - .shipping_details - .async_lift(inner_decrypt) - .await?, - is_payment_processor_token_flow: storage_model.is_payment_processor_token_flow, + charge_id: storage_model.charge_id, + client_source: storage_model.client_source, + client_version: storage_model.client_version, + customer_acceptance: storage_model.customer_acceptance, + profile_id: storage_model.profile_id, organization_id: storage_model.organization_id, - skip_external_tax_calculation: storage_model.skip_external_tax_calculation, + order_tax_amount: storage_model.order_tax_amount, + shipping_cost: storage_model.shipping_cost, }) } .await .change_context(ValidationError::InvalidValue { - message: "Failed while decrypting payment intent".to_string(), + message: "Failed while decrypting payment attempt".to_string(), }) } async fn construct_new(self) -> CustomResult { - Ok(DieselPaymentIntentNew { + let card_network = self + .payment_method_data + .as_ref() + .and_then(|data| data.as_object()) + .and_then(|card| card.get("card")) + .and_then(|data| data.as_object()) + .and_then(|card| card.get("card_network")) + .and_then(|network| network.as_str()) + .map(|network| network.to_string()); + Ok(DieselPaymentAttemptNew { payment_id: self.payment_id, merchant_id: self.merchant_id, + attempt_id: self.attempt_id, status: self.status, amount: self.amount, currency: self.currency, - amount_captured: self.amount_captured, - customer_id: self.customer_id, - description: self.description, - return_url: self.return_url, - metadata: self.metadata, - connector_id: self.connector_id, - shipping_address_id: self.shipping_address_id, - billing_address_id: self.billing_address_id, - statement_descriptor_name: self.statement_descriptor_name, - statement_descriptor_suffix: self.statement_descriptor_suffix, + save_to_locker: self.save_to_locker, + connector: self.connector, + error_message: self.error_message, + offer_amount: self.offer_amount, + surcharge_amount: self.surcharge_amount, + tax_amount: self.tax_amount, + payment_method_id: self.payment_method_id, + payment_method: self.payment_method, + capture_method: self.capture_method, + capture_on: self.capture_on, + confirm: self.confirm, + authentication_type: self.authentication_type, created_at: self.created_at, modified_at: self.modified_at, last_synced: self.last_synced, - setup_future_usage: self.setup_future_usage, - off_session: self.off_session, - client_secret: self.client_secret, - active_attempt_id: self.active_attempt.get_id(), - business_country: self.business_country, - business_label: self.business_label, - order_details: self.order_details, - allowed_payment_method_types: self.allowed_payment_method_types, + cancellation_reason: self.cancellation_reason, + amount_to_capture: self.amount_to_capture, + mandate_id: self.mandate_id, + browser_info: self.browser_info, + payment_token: self.payment_token, + error_code: self.error_code, connector_metadata: self.connector_metadata, - feature_metadata: self.feature_metadata, - attempt_count: self.attempt_count, - profile_id: self.profile_id, - merchant_decision: self.merchant_decision, - payment_link_id: self.payment_link_id, - payment_confirm_source: self.payment_confirm_source, + payment_experience: self.payment_experience, + payment_method_type: self.payment_method_type, + payment_method_data: self.payment_method_data, + business_sub_label: self.business_sub_label, + straight_through_algorithm: self.straight_through_algorithm, + preprocessing_step_id: self.preprocessing_step_id, + mandate_details: self.mandate_details.map(Into::into), + error_reason: self.error_reason, + connector_response_reference_id: self.connector_response_reference_id, + multiple_capture_count: self.multiple_capture_count, + amount_capturable: self.amount_capturable, updated_by: self.updated_by, - surcharge_applicable: self.surcharge_applicable, - request_incremental_authorization: self.request_incremental_authorization, - incremental_authorization_allowed: self.incremental_authorization_allowed, - authorization_count: self.authorization_count, + merchant_connector_id: self.merchant_connector_id, + authentication_data: self.authentication_data, + encoded_data: self.encoded_data, + unified_code: self.unified_code, + unified_message: self.unified_message, + net_amount: Some(self.net_amount), + external_three_ds_authentication_attempted: self + .external_three_ds_authentication_attempted, + authentication_connector: self.authentication_connector, + authentication_id: self.authentication_id, + mandate_data: self.mandate_data.map(Into::into), fingerprint_id: self.fingerprint_id, - session_expiry: self.session_expiry, - request_external_three_ds_authentication: self.request_external_three_ds_authentication, - charges: self.charges, - frm_metadata: self.frm_metadata, - customer_details: self.customer_details.map(Encryption::from), - billing_details: self.billing_details.map(Encryption::from), - merchant_order_reference_id: self.merchant_order_reference_id, - shipping_details: self.shipping_details.map(Encryption::from), - is_payment_processor_token_flow: self.is_payment_processor_token_flow, + payment_method_billing_address_id: self.payment_method_billing_address_id, + charge_id: self.charge_id, + client_source: self.client_source, + client_version: self.client_version, + customer_acceptance: self.customer_acceptance, + profile_id: self.profile_id, organization_id: self.organization_id, + card_network, + order_tax_amount: self.order_tax_amount, + shipping_cost: self.shipping_cost, + }) + } +} + +#[cfg(all(feature = "v2", feature = "payment_v2"))] +#[async_trait::async_trait] +impl behaviour::Conversion for PaymentAttempt { + type DstType = DieselPaymentAttempt; + type NewDstType = DieselPaymentAttemptNew; + + async fn convert(self) -> CustomResult { + let card_network = self + .payment_method_data + .as_ref() + .and_then(|data| data.as_object()) + .and_then(|card| card.get("card")) + .and_then(|data| data.as_object()) + .and_then(|card| card.get("card_network")) + .and_then(|network| network.as_str()) + .map(|network| network.to_string()); + Ok(DieselPaymentAttempt { + payment_id: self.payment_id, + merchant_id: self.merchant_id, + attempt_id: self.attempt_id, + status: self.status, + amount: self.amount, + currency: self.currency, + save_to_locker: self.save_to_locker, + connector: self.connector, + error_message: self.error_message, + offer_amount: self.offer_amount, + surcharge_amount: self.surcharge_amount, + tax_amount: self.tax_amount, + payment_method_id: self.payment_method_id, + payment_method: self.payment_method, + connector_transaction_id: self.connector_transaction_id, + capture_method: self.capture_method, + capture_on: self.capture_on, + confirm: self.confirm, + authentication_type: self.authentication_type, + created_at: self.created_at, + modified_at: self.modified_at, + last_synced: self.last_synced, + cancellation_reason: self.cancellation_reason, + amount_to_capture: self.amount_to_capture, + mandate_id: self.mandate_id, + browser_info: self.browser_info, + error_code: self.error_code, + payment_token: self.payment_token, + connector_metadata: self.connector_metadata, + payment_experience: self.payment_experience, + payment_method_type: self.payment_method_type, + payment_method_data: self.payment_method_data, + business_sub_label: self.business_sub_label, + straight_through_algorithm: self.straight_through_algorithm, + preprocessing_step_id: self.preprocessing_step_id, + mandate_details: self.mandate_details.map(Into::into), + error_reason: self.error_reason, + multiple_capture_count: self.multiple_capture_count, + connector_response_reference_id: self.connector_response_reference_id, + amount_capturable: self.amount_capturable, + updated_by: self.updated_by, + merchant_connector_id: self.merchant_connector_id, + authentication_data: self.authentication_data, + encoded_data: self.encoded_data, + unified_code: self.unified_code, + unified_message: self.unified_message, + net_amount: Some(self.net_amount), + external_three_ds_authentication_attempted: self + .external_three_ds_authentication_attempted, + authentication_connector: self.authentication_connector, + authentication_id: self.authentication_id, + mandate_data: self.mandate_data.map(Into::into), + fingerprint_id: self.fingerprint_id, + payment_method_billing_address_id: self.payment_method_billing_address_id, + charge_id: self.charge_id, + client_source: self.client_source, + client_version: self.client_version, + customer_acceptance: self.customer_acceptance, + profile_id: self.profile_id, + organization_id: self.organization_id, + card_network, + order_tax_amount: self.order_tax_amount, + shipping_cost: self.shipping_cost, + }) + } + + async fn convert_back( + _state: &KeyManagerState, + storage_model: Self::DstType, + _key: &Secret>, + _key_manager_identifier: keymanager::Identifier, + ) -> CustomResult + where + Self: Sized, + { + async { + let net_amount = storage_model.get_or_calculate_net_amount(); + Ok::>(Self { + payment_id: storage_model.payment_id, + merchant_id: storage_model.merchant_id, + attempt_id: storage_model.attempt_id, + status: storage_model.status, + amount: storage_model.amount, + net_amount, + currency: storage_model.currency, + save_to_locker: storage_model.save_to_locker, + connector: storage_model.connector, + error_message: storage_model.error_message, + offer_amount: storage_model.offer_amount, + surcharge_amount: storage_model.surcharge_amount, + tax_amount: storage_model.tax_amount, + payment_method_id: storage_model.payment_method_id, + payment_method: storage_model.payment_method, + connector_transaction_id: storage_model.connector_transaction_id, + capture_method: storage_model.capture_method, + capture_on: storage_model.capture_on, + confirm: storage_model.confirm, + authentication_type: storage_model.authentication_type, + created_at: storage_model.created_at, + modified_at: storage_model.modified_at, + last_synced: storage_model.last_synced, + cancellation_reason: storage_model.cancellation_reason, + amount_to_capture: storage_model.amount_to_capture, + mandate_id: storage_model.mandate_id, + browser_info: storage_model.browser_info, + error_code: storage_model.error_code, + payment_token: storage_model.payment_token, + connector_metadata: storage_model.connector_metadata, + payment_experience: storage_model.payment_experience, + payment_method_type: storage_model.payment_method_type, + payment_method_data: storage_model.payment_method_data, + business_sub_label: storage_model.business_sub_label, + straight_through_algorithm: storage_model.straight_through_algorithm, + preprocessing_step_id: storage_model.preprocessing_step_id, + mandate_details: storage_model.mandate_details.map(Into::into), + error_reason: storage_model.error_reason, + multiple_capture_count: storage_model.multiple_capture_count, + connector_response_reference_id: storage_model.connector_response_reference_id, + amount_capturable: storage_model.amount_capturable, + updated_by: storage_model.updated_by, + authentication_data: storage_model.authentication_data, + encoded_data: storage_model.encoded_data, + merchant_connector_id: storage_model.merchant_connector_id, + unified_code: storage_model.unified_code, + unified_message: storage_model.unified_message, + external_three_ds_authentication_attempted: storage_model + .external_three_ds_authentication_attempted, + authentication_connector: storage_model.authentication_connector, + authentication_id: storage_model.authentication_id, + mandate_data: storage_model.mandate_data.map(Into::into), + payment_method_billing_address_id: storage_model.payment_method_billing_address_id, + fingerprint_id: storage_model.fingerprint_id, + charge_id: storage_model.charge_id, + client_source: storage_model.client_source, + client_version: storage_model.client_version, + customer_acceptance: storage_model.customer_acceptance, + profile_id: storage_model.profile_id, + organization_id: storage_model.organization_id, + order_tax_amount: storage_model.order_tax_amount, + shipping_cost: storage_model.shipping_cost, + }) + } + .await + .change_context(ValidationError::InvalidValue { + message: "Failed while decrypting payment attempt".to_string(), + }) + } + + async fn construct_new(self) -> CustomResult { + let card_network = self + .payment_method_data + .as_ref() + .and_then(|data| data.as_object()) + .and_then(|card| card.get("card")) + .and_then(|data| data.as_object()) + .and_then(|card| card.get("card_network")) + .and_then(|network| network.as_str()) + .map(|network| network.to_string()); + Ok(DieselPaymentAttemptNew { + payment_id: self.payment_id, + merchant_id: self.merchant_id, + attempt_id: self.attempt_id, + status: self.status, + amount: self.amount, + currency: self.currency, + save_to_locker: self.save_to_locker, + connector: self.connector, + error_message: self.error_message, + offer_amount: self.offer_amount, + surcharge_amount: self.surcharge_amount, + tax_amount: self.tax_amount, + payment_method_id: self.payment_method_id, + payment_method: self.payment_method, + capture_method: self.capture_method, + capture_on: self.capture_on, + confirm: self.confirm, + authentication_type: self.authentication_type, + created_at: self.created_at, + modified_at: self.modified_at, + last_synced: self.last_synced, + cancellation_reason: self.cancellation_reason, + amount_to_capture: self.amount_to_capture, + mandate_id: self.mandate_id, + browser_info: self.browser_info, + payment_token: self.payment_token, + error_code: self.error_code, + connector_metadata: self.connector_metadata, + payment_experience: self.payment_experience, + payment_method_type: self.payment_method_type, + payment_method_data: self.payment_method_data, + business_sub_label: self.business_sub_label, + straight_through_algorithm: self.straight_through_algorithm, + preprocessing_step_id: self.preprocessing_step_id, + mandate_details: self.mandate_details.map(Into::into), + error_reason: self.error_reason, + connector_response_reference_id: self.connector_response_reference_id, + multiple_capture_count: self.multiple_capture_count, + amount_capturable: self.amount_capturable, + updated_by: self.updated_by, + merchant_connector_id: self.merchant_connector_id, + authentication_data: self.authentication_data, + encoded_data: self.encoded_data, + unified_code: self.unified_code, + unified_message: self.unified_message, + net_amount: Some(self.net_amount), + external_three_ds_authentication_attempted: self + .external_three_ds_authentication_attempted, + authentication_connector: self.authentication_connector, + authentication_id: self.authentication_id, + mandate_data: self.mandate_data.map(Into::into), + fingerprint_id: self.fingerprint_id, + payment_method_billing_address_id: self.payment_method_billing_address_id, + charge_id: self.charge_id, + client_source: self.client_source, + client_version: self.client_version, + customer_acceptance: self.customer_acceptance, + profile_id: self.profile_id, + organization_id: self.organization_id, + card_network, + order_tax_amount: self.order_tax_amount, shipping_cost: self.shipping_cost, - tax_details: self.tax_details, - skip_external_tax_calculation: self.skip_external_tax_calculation, }) } } diff --git a/crates/hyperswitch_domain_models/src/payments/payment_intent.rs b/crates/hyperswitch_domain_models/src/payments/payment_intent.rs index c4d19c83a3..f5b719fe37 100644 --- a/crates/hyperswitch_domain_models/src/payments/payment_intent.rs +++ b/crates/hyperswitch_domain_models/src/payments/payment_intent.rs @@ -3,16 +3,30 @@ use common_utils::{ consts::{PAYMENTS_LIST_MAX_LIMIT_V1, PAYMENTS_LIST_MAX_LIMIT_V2}, crypto::Encryptable, encryption::Encryption, + errors::{CustomResult, ValidationError}, id_type, pii::{self, Email}, - types::{keymanager::KeyManagerState, MinorUnit}, + type_name, + types::{ + keymanager::{self, KeyManagerState}, + MinorUnit, + }, }; -use masking::{Deserialize, Secret}; +use diesel_models::{ + PaymentIntent as DieselPaymentIntent, PaymentIntentNew as DieselPaymentIntentNew, +}; +use error_stack::ResultExt; +use masking::{Deserialize, PeekInterface, Secret}; use serde::Serialize; use time::PrimitiveDateTime; use super::{payment_attempt::PaymentAttempt, PaymentIntent}; -use crate::{errors, merchant_key_store::MerchantKeyStore, RemoteStorageObject}; +use crate::{ + behaviour, errors, + merchant_key_store::MerchantKeyStore, + type_encryption::{crypto_operation, AsyncLift, CryptoOperation}, + RemoteStorageObject, +}; #[async_trait::async_trait] pub trait PaymentIntentInterface { async fn update_payment_intent( @@ -1563,3 +1577,425 @@ where } } } + +#[cfg(all(feature = "v2", feature = "payment_v2"))] +#[async_trait::async_trait] +impl behaviour::Conversion for PaymentIntent { + type DstType = DieselPaymentIntent; + type NewDstType = DieselPaymentIntentNew; + + async fn convert(self) -> CustomResult { + Ok(DieselPaymentIntent { + merchant_id: self.merchant_id, + status: self.status, + amount: self.amount, + currency: self.currency, + amount_captured: self.amount_captured, + customer_id: self.customer_id, + description: self.description, + return_url: self.return_url, + metadata: self.metadata, + statement_descriptor_name: self.statement_descriptor_name, + created_at: self.created_at, + modified_at: self.modified_at, + last_synced: self.last_synced, + setup_future_usage: self.setup_future_usage, + off_session: self.off_session, + client_secret: self.client_secret, + active_attempt_id: self.active_attempt.get_id(), + order_details: self.order_details, + allowed_payment_method_types: self.allowed_payment_method_types, + connector_metadata: self.connector_metadata, + feature_metadata: self.feature_metadata, + attempt_count: self.attempt_count, + profile_id: self.profile_id, + frm_merchant_decision: self.frm_merchant_decision, + payment_link_id: self.payment_link_id, + payment_confirm_source: self.payment_confirm_source, + updated_by: self.updated_by, + surcharge_applicable: self.surcharge_applicable, + request_incremental_authorization: self.request_incremental_authorization, + authorization_count: self.authorization_count, + session_expiry: self.session_expiry, + request_external_three_ds_authentication: self.request_external_three_ds_authentication, + charges: self.charges, + frm_metadata: self.frm_metadata, + customer_details: self.customer_details.map(Encryption::from), + billing_address: self.billing_address.map(Encryption::from), + merchant_order_reference_id: self.merchant_order_reference_id, + shipping_address: self.shipping_address.map(Encryption::from), + is_payment_processor_token_flow: self.is_payment_processor_token_flow, + capture_method: self.capture_method, + id: self.id, + authentication_type: self.authentication_type, + amount_to_capture: self.amount_to_capture, + prerouting_algorithm: self.prerouting_algorithm, + merchant_reference_id: self.merchant_reference_id, + surcharge_amount: self.surcharge_amount, + tax_on_surcharge: self.tax_on_surcharge, + organization_id: self.organization_id, + shipping_cost: self.shipping_cost, + tax_details: self.tax_details, + skip_external_tax_calculation: self.skip_external_tax_calculation, + }) + } + async fn convert_back( + state: &KeyManagerState, + storage_model: Self::DstType, + key: &Secret>, + key_manager_identifier: keymanager::Identifier, + ) -> CustomResult + where + Self: Sized, + { + async { + let inner_decrypt = |inner| async { + crypto_operation( + state, + type_name!(Self::DstType), + CryptoOperation::DecryptOptional(inner), + key_manager_identifier.clone(), + key.peek(), + ) + .await + .and_then(|val| val.try_into_optionaloperation()) + }; + Ok::>(Self { + merchant_id: storage_model.merchant_id, + status: storage_model.status, + amount: storage_model.amount, + currency: storage_model.currency, + amount_captured: storage_model.amount_captured, + customer_id: storage_model.customer_id, + description: storage_model.description, + return_url: storage_model.return_url, + metadata: storage_model.metadata, + statement_descriptor_name: storage_model.statement_descriptor_name, + created_at: storage_model.created_at, + modified_at: storage_model.modified_at, + last_synced: storage_model.last_synced, + setup_future_usage: storage_model.setup_future_usage, + off_session: storage_model.off_session, + client_secret: storage_model.client_secret, + active_attempt: RemoteStorageObject::ForeignID(storage_model.active_attempt_id), + order_details: storage_model.order_details, + allowed_payment_method_types: storage_model.allowed_payment_method_types, + connector_metadata: storage_model.connector_metadata, + feature_metadata: storage_model.feature_metadata, + attempt_count: storage_model.attempt_count, + profile_id: storage_model.profile_id, + frm_merchant_decision: storage_model.frm_merchant_decision, + payment_link_id: storage_model.payment_link_id, + payment_confirm_source: storage_model.payment_confirm_source, + updated_by: storage_model.updated_by, + surcharge_applicable: storage_model.surcharge_applicable, + request_incremental_authorization: storage_model.request_incremental_authorization, + authorization_count: storage_model.authorization_count, + session_expiry: storage_model.session_expiry, + request_external_three_ds_authentication: storage_model + .request_external_three_ds_authentication, + charges: storage_model.charges, + frm_metadata: storage_model.frm_metadata, + customer_details: storage_model + .customer_details + .async_lift(inner_decrypt) + .await?, + billing_address: storage_model + .billing_address + .async_lift(inner_decrypt) + .await?, + merchant_order_reference_id: storage_model.merchant_order_reference_id, + shipping_address: storage_model + .shipping_address + .async_lift(inner_decrypt) + .await?, + is_payment_processor_token_flow: storage_model.is_payment_processor_token_flow, + capture_method: storage_model.capture_method, + id: storage_model.id, + merchant_reference_id: storage_model.merchant_reference_id, + organization_id: storage_model.organization_id, + authentication_type: storage_model.authentication_type, + amount_to_capture: storage_model.amount_to_capture, + prerouting_algorithm: storage_model.prerouting_algorithm, + surcharge_amount: storage_model.surcharge_amount, + tax_on_surcharge: storage_model.tax_on_surcharge, + shipping_cost: storage_model.shipping_cost, + tax_details: storage_model.tax_details, + skip_external_tax_calculation: storage_model.skip_external_tax_calculation, + }) + } + .await + .change_context(ValidationError::InvalidValue { + message: "Failed while decrypting payment intent".to_string(), + }) + } + + async fn construct_new(self) -> CustomResult { + Ok(DieselPaymentIntentNew { + merchant_id: self.merchant_id, + status: self.status, + amount: self.amount, + currency: self.currency, + amount_captured: self.amount_captured, + customer_id: self.customer_id, + description: self.description, + return_url: self.return_url, + metadata: self.metadata, + statement_descriptor_name: self.statement_descriptor_name, + created_at: self.created_at, + modified_at: self.modified_at, + last_synced: self.last_synced, + setup_future_usage: self.setup_future_usage, + off_session: self.off_session, + client_secret: self.client_secret, + active_attempt_id: self.active_attempt.get_id(), + order_details: self.order_details, + allowed_payment_method_types: self.allowed_payment_method_types, + connector_metadata: self.connector_metadata, + feature_metadata: self.feature_metadata, + attempt_count: self.attempt_count, + profile_id: self.profile_id, + frm_merchant_decision: self.frm_merchant_decision, + payment_link_id: self.payment_link_id, + payment_confirm_source: self.payment_confirm_source, + updated_by: self.updated_by, + surcharge_applicable: self.surcharge_applicable, + request_incremental_authorization: self.request_incremental_authorization, + authorization_count: self.authorization_count, + session_expiry: self.session_expiry, + request_external_three_ds_authentication: self.request_external_three_ds_authentication, + charges: self.charges, + frm_metadata: self.frm_metadata, + customer_details: self.customer_details.map(Encryption::from), + billing_address: self.billing_address.map(Encryption::from), + merchant_order_reference_id: self.merchant_order_reference_id, + shipping_address: self.shipping_address.map(Encryption::from), + is_payment_processor_token_flow: self.is_payment_processor_token_flow, + capture_method: self.capture_method, + id: self.id, + merchant_reference_id: self.merchant_reference_id, + authentication_type: self.authentication_type, + amount_to_capture: self.amount_to_capture, + prerouting_algorithm: self.prerouting_algorithm, + surcharge_amount: self.surcharge_amount, + tax_on_surcharge: self.tax_on_surcharge, + organization_id: self.organization_id, + shipping_cost: self.shipping_cost, + tax_details: self.tax_details, + skip_external_tax_calculation: self.skip_external_tax_calculation, + }) + } +} + +#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] +#[async_trait::async_trait] +impl behaviour::Conversion for PaymentIntent { + type DstType = DieselPaymentIntent; + type NewDstType = DieselPaymentIntentNew; + + async fn convert(self) -> CustomResult { + Ok(DieselPaymentIntent { + payment_id: self.payment_id, + merchant_id: self.merchant_id, + status: self.status, + amount: self.amount, + currency: self.currency, + amount_captured: self.amount_captured, + customer_id: self.customer_id, + description: self.description, + return_url: self.return_url, + metadata: self.metadata, + connector_id: self.connector_id, + shipping_address_id: self.shipping_address_id, + billing_address_id: self.billing_address_id, + statement_descriptor_name: self.statement_descriptor_name, + statement_descriptor_suffix: self.statement_descriptor_suffix, + created_at: self.created_at, + modified_at: self.modified_at, + last_synced: self.last_synced, + setup_future_usage: self.setup_future_usage, + off_session: self.off_session, + client_secret: self.client_secret, + active_attempt_id: self.active_attempt.get_id(), + business_country: self.business_country, + business_label: self.business_label, + order_details: self.order_details, + allowed_payment_method_types: self.allowed_payment_method_types, + connector_metadata: self.connector_metadata, + feature_metadata: self.feature_metadata, + attempt_count: self.attempt_count, + profile_id: self.profile_id, + merchant_decision: self.merchant_decision, + payment_link_id: self.payment_link_id, + payment_confirm_source: self.payment_confirm_source, + updated_by: self.updated_by, + surcharge_applicable: self.surcharge_applicable, + request_incremental_authorization: self.request_incremental_authorization, + incremental_authorization_allowed: self.incremental_authorization_allowed, + authorization_count: self.authorization_count, + fingerprint_id: self.fingerprint_id, + session_expiry: self.session_expiry, + request_external_three_ds_authentication: self.request_external_three_ds_authentication, + charges: self.charges, + frm_metadata: self.frm_metadata, + customer_details: self.customer_details.map(Encryption::from), + billing_details: self.billing_details.map(Encryption::from), + merchant_order_reference_id: self.merchant_order_reference_id, + shipping_details: self.shipping_details.map(Encryption::from), + is_payment_processor_token_flow: self.is_payment_processor_token_flow, + organization_id: self.organization_id, + shipping_cost: self.shipping_cost, + tax_details: self.tax_details, + skip_external_tax_calculation: self.skip_external_tax_calculation, + }) + } + + async fn convert_back( + state: &KeyManagerState, + storage_model: Self::DstType, + key: &Secret>, + key_manager_identifier: keymanager::Identifier, + ) -> CustomResult + where + Self: Sized, + { + async { + let inner_decrypt = |inner| async { + crypto_operation( + state, + type_name!(Self::DstType), + CryptoOperation::DecryptOptional(inner), + key_manager_identifier.clone(), + key.peek(), + ) + .await + .and_then(|val| val.try_into_optionaloperation()) + }; + Ok::>(Self { + payment_id: storage_model.payment_id, + merchant_id: storage_model.merchant_id, + status: storage_model.status, + amount: storage_model.amount, + currency: storage_model.currency, + amount_captured: storage_model.amount_captured, + customer_id: storage_model.customer_id, + description: storage_model.description, + return_url: storage_model.return_url, + metadata: storage_model.metadata, + connector_id: storage_model.connector_id, + shipping_address_id: storage_model.shipping_address_id, + billing_address_id: storage_model.billing_address_id, + statement_descriptor_name: storage_model.statement_descriptor_name, + statement_descriptor_suffix: storage_model.statement_descriptor_suffix, + created_at: storage_model.created_at, + modified_at: storage_model.modified_at, + last_synced: storage_model.last_synced, + setup_future_usage: storage_model.setup_future_usage, + off_session: storage_model.off_session, + client_secret: storage_model.client_secret, + active_attempt: RemoteStorageObject::ForeignID(storage_model.active_attempt_id), + business_country: storage_model.business_country, + business_label: storage_model.business_label, + order_details: storage_model.order_details, + allowed_payment_method_types: storage_model.allowed_payment_method_types, + connector_metadata: storage_model.connector_metadata, + feature_metadata: storage_model.feature_metadata, + attempt_count: storage_model.attempt_count, + profile_id: storage_model.profile_id, + merchant_decision: storage_model.merchant_decision, + payment_link_id: storage_model.payment_link_id, + payment_confirm_source: storage_model.payment_confirm_source, + updated_by: storage_model.updated_by, + surcharge_applicable: storage_model.surcharge_applicable, + request_incremental_authorization: storage_model.request_incremental_authorization, + incremental_authorization_allowed: storage_model.incremental_authorization_allowed, + authorization_count: storage_model.authorization_count, + fingerprint_id: storage_model.fingerprint_id, + session_expiry: storage_model.session_expiry, + request_external_three_ds_authentication: storage_model + .request_external_three_ds_authentication, + charges: storage_model.charges, + frm_metadata: storage_model.frm_metadata, + shipping_cost: storage_model.shipping_cost, + tax_details: storage_model.tax_details, + customer_details: storage_model + .customer_details + .async_lift(inner_decrypt) + .await?, + billing_details: storage_model + .billing_details + .async_lift(inner_decrypt) + .await?, + merchant_order_reference_id: storage_model.merchant_order_reference_id, + shipping_details: storage_model + .shipping_details + .async_lift(inner_decrypt) + .await?, + is_payment_processor_token_flow: storage_model.is_payment_processor_token_flow, + organization_id: storage_model.organization_id, + skip_external_tax_calculation: storage_model.skip_external_tax_calculation, + }) + } + .await + .change_context(ValidationError::InvalidValue { + message: "Failed while decrypting payment intent".to_string(), + }) + } + + async fn construct_new(self) -> CustomResult { + Ok(DieselPaymentIntentNew { + payment_id: self.payment_id, + merchant_id: self.merchant_id, + status: self.status, + amount: self.amount, + currency: self.currency, + amount_captured: self.amount_captured, + customer_id: self.customer_id, + description: self.description, + return_url: self.return_url, + metadata: self.metadata, + connector_id: self.connector_id, + shipping_address_id: self.shipping_address_id, + billing_address_id: self.billing_address_id, + statement_descriptor_name: self.statement_descriptor_name, + statement_descriptor_suffix: self.statement_descriptor_suffix, + created_at: self.created_at, + modified_at: self.modified_at, + last_synced: self.last_synced, + setup_future_usage: self.setup_future_usage, + off_session: self.off_session, + client_secret: self.client_secret, + active_attempt_id: self.active_attempt.get_id(), + business_country: self.business_country, + business_label: self.business_label, + order_details: self.order_details, + allowed_payment_method_types: self.allowed_payment_method_types, + connector_metadata: self.connector_metadata, + feature_metadata: self.feature_metadata, + attempt_count: self.attempt_count, + profile_id: self.profile_id, + merchant_decision: self.merchant_decision, + payment_link_id: self.payment_link_id, + payment_confirm_source: self.payment_confirm_source, + updated_by: self.updated_by, + surcharge_applicable: self.surcharge_applicable, + request_incremental_authorization: self.request_incremental_authorization, + incremental_authorization_allowed: self.incremental_authorization_allowed, + authorization_count: self.authorization_count, + fingerprint_id: self.fingerprint_id, + session_expiry: self.session_expiry, + request_external_three_ds_authentication: self.request_external_three_ds_authentication, + charges: self.charges, + frm_metadata: self.frm_metadata, + customer_details: self.customer_details.map(Encryption::from), + billing_details: self.billing_details.map(Encryption::from), + merchant_order_reference_id: self.merchant_order_reference_id, + shipping_details: self.shipping_details.map(Encryption::from), + is_payment_processor_token_flow: self.is_payment_processor_token_flow, + organization_id: self.organization_id, + shipping_cost: self.shipping_cost, + tax_details: self.tax_details, + skip_external_tax_calculation: self.skip_external_tax_calculation, + }) + } +} diff --git a/crates/router/src/core/customers.rs b/crates/router/src/core/customers.rs index e4eb60982d..a325f41404 100644 --- a/crates/router/src/core/customers.rs +++ b/crates/router/src/core/customers.rs @@ -578,7 +578,7 @@ impl CustomerDeleteBridge for customers::GlobalId { key_manager_state, &self.id, merchant_account.get_id(), - &key_store, + key_store, merchant_account.storage_scheme, ) .await @@ -602,13 +602,9 @@ impl CustomerDeleteBridge for customers::GlobalId { Ok(customer_payment_methods) => { for pm in customer_payment_methods.into_iter() { if pm.payment_method == Some(enums::PaymentMethod::Card) { - cards::delete_card_by_locker_id( - &state, - &self.id, - merchant_account.get_id(), - ) - .await - .switch()?; + cards::delete_card_by_locker_id(state, &self.id, merchant_account.get_id()) + .await + .switch()?; } // No solution as of now, need to discuss this further with payment_method_v2 @@ -676,7 +672,7 @@ impl CustomerDeleteBridge for customers::GlobalId { customer_orig, merchant_account.get_id(), updated_customer, - &key_store, + key_store, merchant_account.storage_scheme, ) .await diff --git a/crates/router/src/core/fraud_check.rs b/crates/router/src/core/fraud_check.rs index 90c36ba9aa..7e184b318d 100644 --- a/crates/router/src/core/fraud_check.rs +++ b/crates/router/src/core/fraud_check.rs @@ -786,6 +786,7 @@ pub async fn frm_fulfillment_core( } } +#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] #[instrument(skip_all)] pub async fn make_fulfillment_api_call( db: &dyn StorageInterface, diff --git a/crates/router/src/core/fraud_check/operation/fraud_check_post.rs b/crates/router/src/core/fraud_check/operation/fraud_check_post.rs index bfb54c8f4e..1a8bc1b554 100644 --- a/crates/router/src/core/fraud_check/operation/fraud_check_post.rs +++ b/crates/router/src/core/fraud_check/operation/fraud_check_post.rs @@ -405,6 +405,7 @@ where frm_router_data: FrmRouterData, ) -> RouterResult { let db = &*state.store; + let key_manager_state = &state.into(); let frm_check_update = match frm_router_data.response { FrmResponse::Sale(response) => match response { Err(err) => Some(FraudCheckUpdate::ErrorUpdate { @@ -569,15 +570,30 @@ where ), }; + let payment_attempt_update = PaymentAttemptUpdate::RejectUpdate { + status: payment_attempt_status, + error_code: Some(Some(frm_data.fraud_check.frm_status.to_string())), + error_message, + updated_by: frm_data.merchant_account.storage_scheme.to_string(), + }; + + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] let payment_attempt = db .update_payment_attempt_with_attempt_id( payment_data.get_payment_attempt().clone(), - PaymentAttemptUpdate::RejectUpdate { - status: payment_attempt_status, - error_code: Some(Some(frm_data.fraud_check.frm_status.to_string())), - error_message, - updated_by: frm_data.merchant_account.storage_scheme.to_string(), - }, + payment_attempt_update, + frm_data.merchant_account.storage_scheme, + ) + .await + .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?; + + #[cfg(all(feature = "v2", feature = "payment_v2"))] + let payment_attempt = db + .update_payment_attempt_with_attempt_id( + key_manager_state, + key_store, + payment_data.get_payment_attempt().clone(), + payment_attempt_update, frm_data.merchant_account.storage_scheme, ) .await @@ -587,7 +603,7 @@ where let payment_intent = db .update_payment_intent( - &state.into(), + key_manager_state, payment_data.get_payment_intent().clone(), PaymentIntentUpdate::RejectUpdate { status: payment_intent_status, diff --git a/crates/router/src/core/payment_methods/cards.rs b/crates/router/src/core/payment_methods/cards.rs index 1b23dcab19..22350f77e6 100644 --- a/crates/router/src/core/payment_methods/cards.rs +++ b/crates/router/src/core/payment_methods/cards.rs @@ -2046,7 +2046,7 @@ pub async fn delete_card_from_locker( #[cfg(all(feature = "v2", feature = "customer_v2"))] pub async fn delete_card_by_locker_id( state: &routes::SessionState, - id: &String, + id: &str, merchant_id: &id_type::MerchantId, ) -> errors::RouterResult { todo!() @@ -2472,7 +2472,7 @@ pub async fn delete_card_from_hs_locker<'a>( #[instrument(skip_all)] pub async fn delete_card_from_hs_locker_by_global_id<'a>( state: &routes::SessionState, - id: &String, + id: &str, merchant_id: &id_type::MerchantId, card_reference: &'a str, ) -> errors::RouterResult { @@ -4706,6 +4706,7 @@ async fn get_pm_list_context( Ok(payment_method_retrieval_context) } +#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn perform_surcharge_ops( payment_intent: Option, state: &routes::SessionState, @@ -4750,6 +4751,18 @@ async fn perform_surcharge_ops( Ok(()) } +#[cfg(all(feature = "v2", feature = "payment_v2"))] +async fn perform_surcharge_ops( + _payment_intent: Option, + _state: &routes::SessionState, + _merchant_account: domain::MerchantAccount, + _key_store: domain::MerchantKeyStore, + _business_profile: Option, + _response: &mut api::CustomerPaymentMethodsListResponse, +) -> Result<(), error_stack::Report> { + todo!() +} + #[cfg(all(feature = "v2", feature = "payment_methods_v2"))] struct SavedPMLPaymentsInfo { pub payment_intent: storage::PaymentIntent, diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index 2af3c52d75..a1d92d8a99 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -3757,6 +3757,7 @@ pub enum AttemptType { } impl AttemptType { + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] // The function creates a new payment_attempt from the previous payment attempt but doesn't populate fields like payment_method, error_code etc. // Logic to override the fields with data provided in the request should be done after this if required. // In case if fields are not overridden by the request then they contain the same data that was in the previous attempt provided it is populated in this function. @@ -3851,6 +3852,20 @@ impl AttemptType { } } + #[cfg(all(feature = "v2", feature = "payment_v2"))] + // The function creates a new payment_attempt from the previous payment attempt but doesn't populate fields like payment_method, error_code etc. + // Logic to override the fields with data provided in the request should be done after this if required. + // In case if fields are not overridden by the request then they contain the same data that was in the previous attempt provided it is populated in this function. + #[inline(always)] + fn make_new_payment_attempt( + _payment_method_data: Option<&api_models::payments::PaymentMethodData>, + _old_payment_attempt: PaymentAttempt, + _new_attempt_count: i16, + _storage_scheme: enums::MerchantStorageScheme, + ) -> PaymentAttempt { + todo!() + } + #[instrument(skip_all)] pub async fn modify_payment_intent_and_payment_attempt( &self, @@ -3865,19 +3880,34 @@ impl AttemptType { Self::SameOld => Ok((fetched_payment_intent, fetched_payment_attempt)), Self::New => { let db = &*state.store; + let key_manager_state = &state.into(); let new_attempt_count = fetched_payment_intent.attempt_count + 1; + let new_payment_attempt_to_insert = Self::make_new_payment_attempt( + request + .payment_method_data + .as_ref() + .and_then(|request_payment_method_data| { + request_payment_method_data.payment_method_data.as_ref() + }), + fetched_payment_attempt, + new_attempt_count, + storage_scheme, + ); + + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] + let new_payment_attempt = db + .insert_payment_attempt(new_payment_attempt_to_insert, storage_scheme) + .await + .to_duplicate_response(errors::ApiErrorResponse::DuplicatePayment { + payment_id: fetched_payment_intent.get_id().to_owned(), + })?; + + #[cfg(all(feature = "v2", feature = "payment_v2"))] let new_payment_attempt = db .insert_payment_attempt( - Self::make_new_payment_attempt( - request.payment_method_data.as_ref().and_then( - |request_payment_method_data| { - request_payment_method_data.payment_method_data.as_ref() - }, - ), - fetched_payment_attempt, - new_attempt_count, - storage_scheme, - ), + key_manager_state, + key_store, + new_payment_attempt_to_insert, storage_scheme, ) .await @@ -3887,7 +3917,7 @@ impl AttemptType { let updated_payment_intent = db .update_payment_intent( - &state.into(), + key_manager_state, fetched_payment_intent, storage::PaymentIntentUpdate::StatusAndAttemptUpdate { status: payment_intent_status_fsm( diff --git a/crates/router/src/core/payments/operations/payment_create.rs b/crates/router/src/core/payments/operations/payment_create.rs index fb6bb04477..f397ecd8a2 100644 --- a/crates/router/src/core/payments/operations/payment_create.rs +++ b/crates/router/src/core/payments/operations/payment_create.rs @@ -77,7 +77,6 @@ impl GetTracker, api::PaymentsRequest> for Pa let ephemeral_key = Self::get_ephemeral_key(request, state, merchant_account).await; let merchant_id = merchant_account.get_id(); let storage_scheme = merchant_account.storage_scheme; - let (payment_intent, payment_attempt); let money @ (amount, currency) = payments_create_request_validation(request)?; @@ -322,9 +321,9 @@ impl GetTracker, api::PaymentsRequest> for Pa ) .await?; - payment_intent = db + let payment_intent = db .insert_payment_intent( - &state.into(), + key_manager_state, payment_intent_new, merchant_key_store, storage_scheme, @@ -342,12 +341,27 @@ impl GetTracker, api::PaymentsRequest> for Pa )?; } - payment_attempt = db + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] + let payment_attempt = db .insert_payment_attempt(payment_attempt_new, storage_scheme) .await .to_duplicate_response(errors::ApiErrorResponse::DuplicatePayment { payment_id: payment_id.clone(), })?; + + #[cfg(all(feature = "v2", feature = "payment_v2"))] + let payment_attempt = db + .insert_payment_attempt( + key_manager_state, + merchant_key_store, + payment_attempt_new, + storage_scheme, + ) + .await + .to_duplicate_response(errors::ApiErrorResponse::DuplicatePayment { + payment_id: payment_id.clone(), + })?; + let mandate_details_present = payment_attempt.mandate_details.is_some(); helpers::validate_mandate_data_and_future_usage( diff --git a/crates/router/src/core/payments/operations/payment_response.rs b/crates/router/src/core/payments/operations/payment_response.rs index 24ee0697ac..fb09b4d8b6 100644 --- a/crates/router/src/core/payments/operations/payment_response.rs +++ b/crates/router/src/core/payments/operations/payment_response.rs @@ -246,6 +246,11 @@ impl PostUpdateTracker, types::PaymentsAuthor payment_method_id, updated_by: storage_scheme.clone().to_string(), }; + + #[cfg(all( + any(feature = "v1", feature = "v2"), + not(feature = "payment_v2") + ))] let respond = state .store .update_payment_attempt_with_attempt_id( @@ -254,6 +259,19 @@ impl PostUpdateTracker, types::PaymentsAuthor storage_scheme, ) .await; + + #[cfg(all(feature = "v2", feature = "payment_v2"))] + let respond = state + .store + .update_payment_attempt_with_attempt_id( + &(&state).into(), + &key_store, + payment_attempt, + payment_attempt_update, + storage_scheme, + ) + .await; + if let Err(err) = respond { logger::error!("Error updating payment attempt: {:?}", err); }; @@ -325,15 +343,33 @@ impl PostUpdateTracker, types::PaymentsIncrementalAu }; //payment_attempt update if let Some(payment_attempt_update) = option_payment_attempt_update { - payment_data.payment_attempt = state - .store - .update_payment_attempt_with_attempt_id( - payment_data.payment_attempt.clone(), - payment_attempt_update, - storage_scheme, - ) - .await - .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?; + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] + { + payment_data.payment_attempt = state + .store + .update_payment_attempt_with_attempt_id( + payment_data.payment_attempt.clone(), + payment_attempt_update, + storage_scheme, + ) + .await + .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?; + } + + #[cfg(all(feature = "v2", feature = "payment_v2"))] + { + payment_data.payment_attempt = state + .store + .update_payment_attempt_with_attempt_id( + &state.into(), + key_store, + payment_data.payment_attempt.clone(), + payment_attempt_update, + storage_scheme, + ) + .await + .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?; + } } // payment_intent update if let Some(payment_intent_update) = option_payment_intent_update { diff --git a/crates/router/src/core/payments/retry.rs b/crates/router/src/core/payments/retry.rs index 75c0fb6d77..ce2456e08c 100644 --- a/crates/router/src/core/payments/retry.rs +++ b/crates/router/src/core/payments/retry.rs @@ -360,6 +360,7 @@ where ); let db = &*state.store; + let key_manager_state = &state.into(); let additional_payment_method_data = payments::helpers::update_additional_payment_data_with_connector_response_pm_data( payment_data @@ -389,43 +390,57 @@ where .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Could not parse the connector response")?; + let payment_attempt_update = storage::PaymentAttemptUpdate::ResponseUpdate { + status: router_data.status, + connector: None, + connector_transaction_id: match resource_id { + types::ResponseId::NoResponseId => None, + types::ResponseId::ConnectorTransactionId(id) + | types::ResponseId::EncodedData(id) => Some(id), + }, + connector_response_reference_id: payment_data + .get_payment_attempt() + .connector_response_reference_id + .clone(), + authentication_type: None, + payment_method_id: payment_data.get_payment_attempt().payment_method_id.clone(), + mandate_id: payment_data + .get_mandate_id() + .and_then(|mandate| mandate.mandate_id.clone()), + connector_metadata, + payment_token: None, + error_code: None, + error_message: None, + error_reason: None, + amount_capturable: if router_data.status.is_terminal_status() { + Some(MinorUnit::new(0)) + } else { + None + }, + updated_by: storage_scheme.to_string(), + authentication_data, + encoded_data, + unified_code: None, + unified_message: None, + payment_method_data: additional_payment_method_data, + charge_id, + }; + + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] db.update_payment_attempt_with_attempt_id( payment_data.get_payment_attempt().clone(), - storage::PaymentAttemptUpdate::ResponseUpdate { - status: router_data.status, - connector: None, - connector_transaction_id: match resource_id { - types::ResponseId::NoResponseId => None, - types::ResponseId::ConnectorTransactionId(id) - | types::ResponseId::EncodedData(id) => Some(id), - }, - connector_response_reference_id: payment_data - .get_payment_attempt() - .connector_response_reference_id - .clone(), - authentication_type: None, - payment_method_id: payment_data.get_payment_attempt().payment_method_id.clone(), - mandate_id: payment_data - .get_mandate_id() - .and_then(|mandate| mandate.mandate_id.clone()), - connector_metadata, - payment_token: None, - error_code: None, - error_message: None, - error_reason: None, - amount_capturable: if router_data.status.is_terminal_status() { - Some(MinorUnit::new(0)) - } else { - None - }, - updated_by: storage_scheme.to_string(), - authentication_data, - encoded_data, - unified_code: None, - unified_message: None, - payment_method_data: additional_payment_method_data, - charge_id, - }, + payment_attempt_update, + storage_scheme, + ) + .await + .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?; + + #[cfg(all(feature = "v2", feature = "payment_v2"))] + db.update_payment_attempt_with_attempt_id( + key_manager_state, + key_store, + payment_data.get_payment_attempt().clone(), + payment_attempt_update, storage_scheme, ) .await @@ -445,22 +460,36 @@ where None }; + let payment_attempt_update = storage::PaymentAttemptUpdate::ErrorUpdate { + connector: None, + error_code: Some(Some(error_response.code.clone())), + error_message: Some(Some(error_response.message.clone())), + status: storage_enums::AttemptStatus::Failure, + error_reason: Some(error_response.reason.clone()), + amount_capturable: Some(MinorUnit::new(0)), + updated_by: storage_scheme.to_string(), + unified_code: option_gsm.clone().map(|gsm| gsm.unified_code), + unified_message: option_gsm.map(|gsm| gsm.unified_message), + connector_transaction_id: error_response.connector_transaction_id.clone(), + payment_method_data: additional_payment_method_data, + authentication_type: auth_update, + }; + + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] db.update_payment_attempt_with_attempt_id( payment_data.get_payment_attempt().clone(), - storage::PaymentAttemptUpdate::ErrorUpdate { - connector: None, - error_code: Some(Some(error_response.code.clone())), - error_message: Some(Some(error_response.message.clone())), - status: storage_enums::AttemptStatus::Failure, - error_reason: Some(error_response.reason.clone()), - amount_capturable: Some(MinorUnit::new(0)), - updated_by: storage_scheme.to_string(), - unified_code: option_gsm.clone().map(|gsm| gsm.unified_code), - unified_message: option_gsm.map(|gsm| gsm.unified_message), - connector_transaction_id: error_response.connector_transaction_id.clone(), - payment_method_data: additional_payment_method_data, - authentication_type: auth_update, - }, + payment_attempt_update, + storage_scheme, + ) + .await + .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?; + + #[cfg(all(feature = "v2", feature = "payment_v2"))] + db.update_payment_attempt_with_attempt_id( + key_manager_state, + key_store, + payment_data.get_payment_attempt().clone(), + payment_attempt_update, storage_scheme, ) .await @@ -468,6 +497,7 @@ where } } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] let payment_attempt = db .insert_payment_attempt(new_payment_attempt, storage_scheme) .await @@ -475,12 +505,25 @@ where payment_id: payment_data.get_payment_intent().get_id().to_owned(), })?; + #[cfg(all(feature = "v2", feature = "payment_v2"))] + let payment_attempt = db + .insert_payment_attempt( + key_manager_state, + key_store, + new_payment_attempt, + storage_scheme, + ) + .await + .to_duplicate_response(errors::ApiErrorResponse::DuplicatePayment { + payment_id: payment_data.get_payment_intent().get_id().to_owned(), + })?; + // update payment_attempt, connector_response and payment_intent in payment_data payment_data.set_payment_attempt(payment_attempt); let payment_intent = db .update_payment_intent( - &state.into(), + key_manager_state, payment_data.get_payment_intent().clone(), storage::PaymentIntentUpdate::PaymentAttemptAndAttemptCountUpdate { active_attempt_id: payment_data.get_payment_attempt().attempt_id.clone(), @@ -498,6 +541,7 @@ where Ok(()) } +#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] #[instrument(skip_all)] pub fn make_new_payment_attempt( connector: String, @@ -540,6 +584,9 @@ pub fn make_new_payment_attempt( created_at, modified_at, last_synced, + profile_id: old_payment_attempt.profile_id, + organization_id: old_payment_attempt.organization_id, + shipping_cost: old_payment_attempt.shipping_cost, net_amount: Default::default(), error_message: Default::default(), cancellation_reason: Default::default(), @@ -569,13 +616,21 @@ pub fn make_new_payment_attempt( fingerprint_id: Default::default(), charge_id: Default::default(), customer_acceptance: Default::default(), - profile_id: old_payment_attempt.profile_id, - organization_id: old_payment_attempt.organization_id, - shipping_cost: old_payment_attempt.shipping_cost, - order_tax_amount: None, + order_tax_amount: Default::default(), } } +#[cfg(all(feature = "v2", feature = "payment_v2"))] +#[instrument(skip_all)] +pub fn make_new_payment_attempt( + _connector: String, + _old_payment_attempt: storage::PaymentAttempt, + _new_attempt_count: i16, + _is_step_up: bool, +) -> storage::PaymentAttempt { + todo!() +} + pub async fn config_should_call_gsm( db: &dyn StorageInterface, merchant_id: &common_utils::id_type::MerchantId, diff --git a/crates/router/src/core/payments/routing.rs b/crates/router/src/core/payments/routing.rs index 7e703967a5..5143068db9 100644 --- a/crates/router/src/core/payments/routing.rs +++ b/crates/router/src/core/payments/routing.rs @@ -1095,7 +1095,7 @@ async fn perform_session_routing_for_pm_type( &session_pm_input.state.clone(), merchant_id, algorithm_id, - &session_pm_input.profile_id, + session_pm_input.profile_id, transaction_type, ) .await?; @@ -1124,7 +1124,7 @@ async fn perform_session_routing_for_pm_type( chosen_connectors, session_pm_input.backend_input.clone(), None, - &session_pm_input.profile_id, + session_pm_input.profile_id, transaction_type, ) .await?; @@ -1140,7 +1140,7 @@ async fn perform_session_routing_for_pm_type( fallback, session_pm_input.backend_input.clone(), None, - &session_pm_input.profile_id, + session_pm_input.profile_id, transaction_type, ) .await?; diff --git a/crates/router/src/db/kafka_store.rs b/crates/router/src/db/kafka_store.rs index 4892e2552e..4dc7721185 100644 --- a/crates/router/src/db/kafka_store.rs +++ b/crates/router/src/db/kafka_store.rs @@ -851,7 +851,7 @@ impl MandateInterface for KafkaStore { #[cfg(all(feature = "v2", feature = "customer_v2"))] async fn find_mandate_by_global_id( &self, - id: &String, + id: &str, ) -> CustomResult, errors::StorageError> { self.diesel_store.find_mandate_by_global_id(id).await } @@ -1332,6 +1332,7 @@ impl QueueInterface for KafkaStore { #[async_trait::async_trait] impl PaymentAttemptInterface for KafkaStore { + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn insert_payment_attempt( &self, payment_attempt: storage::PaymentAttemptNew, @@ -1353,6 +1354,36 @@ impl PaymentAttemptInterface for KafkaStore { Ok(attempt) } + #[cfg(all(feature = "v2", feature = "payment_v2"))] + async fn insert_payment_attempt( + &self, + key_manager_state: &KeyManagerState, + merchant_key_store: &domain::MerchantKeyStore, + payment_attempt: storage::PaymentAttempt, + storage_scheme: MerchantStorageScheme, + ) -> CustomResult { + let attempt = self + .diesel_store + .insert_payment_attempt( + key_manager_state, + merchant_key_store, + payment_attempt, + storage_scheme, + ) + .await?; + + if let Err(er) = self + .kafka_producer + .log_payment_attempt(&attempt, None, self.tenant_id.clone()) + .await + { + logger::error!(message="Failed to log analytics event for payment attempt {attempt:?}", error_message=?er) + } + + Ok(attempt) + } + + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn update_payment_attempt_with_attempt_id( &self, this: storage::PaymentAttempt, @@ -1375,6 +1406,38 @@ impl PaymentAttemptInterface for KafkaStore { Ok(attempt) } + #[cfg(all(feature = "v2", feature = "payment_v2"))] + async fn update_payment_attempt_with_attempt_id( + &self, + key_manager_state: &KeyManagerState, + merchant_key_store: &domain::MerchantKeyStore, + this: storage::PaymentAttempt, + payment_attempt: storage::PaymentAttemptUpdate, + storage_scheme: MerchantStorageScheme, + ) -> CustomResult { + let attempt = self + .diesel_store + .update_payment_attempt_with_attempt_id( + key_manager_state, + merchant_key_store, + this.clone(), + payment_attempt, + storage_scheme, + ) + .await?; + + if let Err(er) = self + .kafka_producer + .log_payment_attempt(&attempt, Some(this), self.tenant_id.clone()) + .await + { + logger::error!(message="Failed to log analytics event for payment attempt {attempt:?}", error_message=?er) + } + + Ok(attempt) + } + + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn find_payment_attempt_by_connector_transaction_id_payment_id_merchant_id( &self, connector_transaction_id: &str, @@ -1392,6 +1455,7 @@ impl PaymentAttemptInterface for KafkaStore { .await } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn find_payment_attempt_by_merchant_id_connector_txn_id( &self, merchant_id: &id_type::MerchantId, @@ -1407,6 +1471,7 @@ impl PaymentAttemptInterface for KafkaStore { .await } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn find_payment_attempt_by_payment_id_merchant_id_attempt_id( &self, payment_id: &id_type::PaymentId, @@ -1424,6 +1489,7 @@ impl PaymentAttemptInterface for KafkaStore { .await } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn find_payment_attempt_by_attempt_id_merchant_id( &self, attempt_id: &str, @@ -1435,6 +1501,27 @@ impl PaymentAttemptInterface for KafkaStore { .await } + #[cfg(all(feature = "v2", feature = "payment_v2"))] + async fn find_payment_attempt_by_attempt_id_merchant_id( + &self, + key_manager_state: &KeyManagerState, + merchant_key_store: &domain::MerchantKeyStore, + attempt_id: &str, + merchant_id: &id_type::MerchantId, + storage_scheme: MerchantStorageScheme, + ) -> CustomResult { + self.diesel_store + .find_payment_attempt_by_attempt_id_merchant_id( + key_manager_state, + merchant_key_store, + attempt_id, + merchant_id, + storage_scheme, + ) + .await + } + + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn find_payment_attempt_last_successful_attempt_by_payment_id_merchant_id( &self, payment_id: &id_type::PaymentId, @@ -1450,6 +1537,7 @@ impl PaymentAttemptInterface for KafkaStore { .await } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn find_payment_attempt_last_successful_or_partially_captured_attempt_by_payment_id_merchant_id( &self, payment_id: &id_type::PaymentId, @@ -1465,6 +1553,7 @@ impl PaymentAttemptInterface for KafkaStore { .await } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn find_payment_attempt_by_preprocessing_id_merchant_id( &self, preprocessing_id: &str, @@ -1480,6 +1569,7 @@ impl PaymentAttemptInterface for KafkaStore { .await } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn get_filters_for_payments( &self, pi: &[hyperswitch_domain_models::payments::PaymentIntent], @@ -1494,6 +1584,7 @@ impl PaymentAttemptInterface for KafkaStore { .await } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn get_total_count_of_filtered_payment_attempts( &self, merchant_id: &id_type::MerchantId, @@ -1521,6 +1612,7 @@ impl PaymentAttemptInterface for KafkaStore { .await } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn find_attempts_by_merchant_id_payment_id( &self, merchant_id: &id_type::MerchantId, @@ -1769,7 +1861,7 @@ impl PaymentMethodInterface for KafkaStore { &self, state: &KeyManagerState, key_store: &domain::MerchantKeyStore, - id: &String, + id: &str, limit: Option, ) -> CustomResult, errors::StorageError> { self.diesel_store diff --git a/crates/router/src/db/mandate.rs b/crates/router/src/db/mandate.rs index 2435649447..40e5f88614 100644 --- a/crates/router/src/db/mandate.rs +++ b/crates/router/src/db/mandate.rs @@ -32,7 +32,7 @@ pub trait MandateInterface { #[cfg(all(feature = "v2", feature = "customer_v2"))] async fn find_mandate_by_global_id( &self, - id: &String, + id: &str, ) -> CustomResult, errors::StorageError>; async fn update_mandate_by_merchant_id_mandate_id( @@ -203,7 +203,7 @@ mod storage { #[instrument(skip_all)] async fn find_mandate_by_global_id( &self, - id: &String, + id: &str, ) -> CustomResult, errors::StorageError> { let conn = connection::pg_connection_read(self).await?; storage_types::Mandate::find_by_global_id(&conn, id) @@ -459,7 +459,7 @@ mod storage { #[instrument(skip_all)] async fn find_mandate_by_global_id( &self, - customer_id: &String, + customer_id: &str, ) -> CustomResult, errors::StorageError> { let conn = connection::pg_connection_read(self).await?; storage_types::Mandate::find_by_global_id(&conn, customer_id) @@ -572,7 +572,7 @@ impl MandateInterface for MockDb { #[cfg(all(feature = "v2", feature = "customer_v2"))] async fn find_mandate_by_global_id( &self, - id: &String, + id: &str, ) -> CustomResult, errors::StorageError> { todo!() } diff --git a/crates/router/src/db/payment_method.rs b/crates/router/src/db/payment_method.rs index 0541491ab9..cf263def41 100644 --- a/crates/router/src/db/payment_method.rs +++ b/crates/router/src/db/payment_method.rs @@ -53,7 +53,7 @@ pub trait PaymentMethodInterface { &self, state: &KeyManagerState, key_store: &domain::MerchantKeyStore, - id: &String, + id: &str, limit: Option, ) -> CustomResult, errors::StorageError>; @@ -715,7 +715,7 @@ mod storage { &self, _state: &KeyManagerState, _key_store: &domain::MerchantKeyStore, - _id: &String, + _id: &str, _limit: Option, ) -> CustomResult, errors::StorageError> { todo!() @@ -1129,7 +1129,7 @@ mod storage { &self, state: &KeyManagerState, key_store: &domain::MerchantKeyStore, - id: &String, + id: &str, limit: Option, ) -> CustomResult, errors::StorageError> { let conn = connection::pg_connection_read(self).await?; @@ -1409,7 +1409,7 @@ impl PaymentMethodInterface for MockDb { &self, state: &KeyManagerState, key_store: &domain::MerchantKeyStore, - _id: &String, + _id: &str, _limit: Option, ) -> CustomResult, errors::StorageError> { todo!() diff --git a/crates/router/src/routes/app.rs b/crates/router/src/routes/app.rs index d66dc8e51e..2bafe504dd 100644 --- a/crates/router/src/routes/app.rs +++ b/crates/router/src/routes/app.rs @@ -1576,13 +1576,13 @@ impl BusinessProfile { pub fn server(state: AppState) -> Scope { web::scope("/v2/profiles") .app_data(web::Data::new(state)) - .service(web::resource("").route(web::post().to(super::admin::business_profile_create))) + .service(web::resource("").route(web::post().to(admin::business_profile_create))) .service( web::scope("/{profile_id}") .service( web::resource("") - .route(web::get().to(super::admin::business_profile_retrieve)) - .route(web::put().to(super::admin::business_profile_update)), + .route(web::get().to(admin::business_profile_retrieve)) + .route(web::put().to(admin::business_profile_update)), ) .service( web::resource("/connector_accounts") diff --git a/crates/router/src/types/api/admin.rs b/crates/router/src/types/api/admin.rs index 549c544f30..e30a6ccc1f 100644 --- a/crates/router/src/types/api/admin.rs +++ b/crates/router/src/types/api/admin.rs @@ -189,7 +189,7 @@ impl ForeignTryFrom for BusinessProfileResponse { let order_fulfillment_time = item .order_fulfillment_time - .map(api_models::admin::OrderFulfillmentTime::new) + .map(api_models::admin::OrderFulfillmentTime::try_new) .transpose() .change_context(errors::ParsingError::IntegerOverflow)?; diff --git a/crates/router/src/types/domain/user.rs b/crates/router/src/types/domain/user.rs index 8d6fb1a8ff..725cefb8c4 100644 --- a/crates/router/src/types/domain/user.rs +++ b/crates/router/src/types/domain/user.rs @@ -401,7 +401,7 @@ impl NewUserMerchant { let merchant_name = if let Some(company_name) = self.company_name.clone() { MerchantName::try_from(company_name) } else { - MerchantName::new("merchant".to_string()) + MerchantName::try_new("merchant".to_string()) .change_context(UserErrors::InternalServerError) .attach_printable("merchant name validation failed") } diff --git a/crates/router/src/types/storage/payment_attempt.rs b/crates/router/src/types/storage/payment_attempt.rs index 782d5ae76a..18b6e8cc6f 100644 --- a/crates/router/src/types/storage/payment_attempt.rs +++ b/crates/router/src/types/storage/payment_attempt.rs @@ -85,7 +85,11 @@ impl AttemptStatusExt for enums::AttemptStatus { } #[cfg(test)] -#[cfg(feature = "dummy_connector")] +#[cfg(all( + any(feature = "v1", feature = "v2"), + not(feature = "payment_v2"), // Ignoring tests for v2 since they aren't actively running + feature = "dummy_connector" +))] mod tests { #![allow(clippy::expect_used, clippy::unwrap_used, clippy::print_stderr)] use tokio::sync::oneshot; diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs index 46210d4dd0..1442f5b8d4 100644 --- a/crates/router/src/types/transformers.rs +++ b/crates/router/src/types/transformers.rs @@ -10,7 +10,6 @@ use common_utils::{ ext_traits::{Encode, StringExt, ValueExt}, fp_utils::when, pii, - types::MinorUnit, }; use diesel_models::enums as storage_enums; use error_stack::{report, ResultExt}; @@ -376,7 +375,7 @@ impl ForeignTryFrom for common_enums::RoutableConnectors { impl ForeignFrom for payments::MandateAmountData { fn foreign_from(from: storage_enums::MandateAmountData) -> Self { Self { - amount: MinorUnit::new(from.amount), + amount: from.amount, currency: from.currency, start_date: from.start_date, end_date: from.end_date, @@ -443,7 +442,7 @@ impl ForeignFrom for hyperswitch_domain_models::mandates: impl ForeignFrom for storage_enums::MandateAmountData { fn foreign_from(from: payments::MandateAmountData) -> Self { Self { - amount: from.amount.get_amount_as_i64(), + amount: from.amount, currency: from.currency, start_date: from.start_date, end_date: from.end_date, diff --git a/crates/router/src/utils.rs b/crates/router/src/utils.rs index 12a26cf7c8..b603b86a72 100644 --- a/crates/router/src/utils.rs +++ b/crates/router/src/utils.rs @@ -378,6 +378,9 @@ pub async fn get_mca_from_payment_intent( connector_name: &str, ) -> CustomResult { let db = &*state.store; + let key_manager_state: &KeyManagerState = &state.into(); + + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] let payment_attempt = db .find_payment_attempt_by_attempt_id_merchant_id( &payment_intent.active_attempt.get_id(), @@ -386,7 +389,19 @@ pub async fn get_mca_from_payment_intent( ) .await .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?; - let key_manager_state: &KeyManagerState = &state.into(); + + #[cfg(all(feature = "v2", feature = "payment_v2"))] + let payment_attempt = db + .find_payment_attempt_by_attempt_id_merchant_id( + key_manager_state, + key_store, + &payment_intent.active_attempt.get_id(), + merchant_account.get_id(), + merchant_account.storage_scheme, + ) + .await + .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?; + match payment_attempt.merchant_connector_id { Some(merchant_connector_id) => { #[cfg(feature = "v1")] diff --git a/crates/router/src/utils/user/sample_data.rs b/crates/router/src/utils/user/sample_data.rs index 7147c5071c..f030df01fc 100644 --- a/crates/router/src/utils/user/sample_data.rs +++ b/crates/router/src/utils/user/sample_data.rs @@ -262,7 +262,7 @@ pub async fn generate_sample_data( true => common_enums::AttemptStatus::Failure, _ => common_enums::AttemptStatus::Charged, }, - amount: amount * 100, + amount: MinorUnit::new(amount * 100), currency: payment_intent.currency, connector: Some( (*connector_vec @@ -289,7 +289,7 @@ pub async fn generate_sample_data( created_at, modified_at, last_synced: Some(last_synced), - amount_to_capture: Some(amount * 100), + amount_to_capture: Some(MinorUnit::new(amount * 100)), connector_response_reference_id: Some(attempt_id.clone()), updated_by: merchant_from_db.storage_scheme.to_string(), save_to_locker: None, @@ -312,7 +312,7 @@ pub async fn generate_sample_data( mandate_details: None, error_reason: None, multiple_capture_count: None, - amount_capturable: i64::default(), + amount_capturable: MinorUnit::new(i64::default()), merchant_connector_id: None, authentication_data: None, encoded_data: None, diff --git a/crates/storage_impl/src/mock_db/payment_attempt.rs b/crates/storage_impl/src/mock_db/payment_attempt.rs index 6558c14ace..1a4595bdbb 100644 --- a/crates/storage_impl/src/mock_db/payment_attempt.rs +++ b/crates/storage_impl/src/mock_db/payment_attempt.rs @@ -1,6 +1,10 @@ use api_models::enums::{AuthenticationType, Connector, PaymentMethod, PaymentMethodType}; use common_utils::errors::CustomResult; +#[cfg(all(feature = "v2", feature = "payment_v2"))] +use common_utils::types::keymanager::KeyManagerState; use diesel_models::enums as storage_enums; +#[cfg(all(feature = "v2", feature = "payment_v2"))] +use hyperswitch_domain_models::merchant_key_store::MerchantKeyStore; use hyperswitch_domain_models::{ errors::StorageError, payments::payment_attempt::{ @@ -13,6 +17,7 @@ use crate::DataModelExt; #[async_trait::async_trait] impl PaymentAttemptInterface for MockDb { + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn find_payment_attempt_by_payment_id_merchant_id_attempt_id( &self, _payment_id: &common_utils::id_type::PaymentId, @@ -24,6 +29,7 @@ impl PaymentAttemptInterface for MockDb { Err(StorageError::MockDbError)? } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn get_filters_for_payments( &self, _pi: &[hyperswitch_domain_models::payments::PaymentIntent], @@ -36,6 +42,7 @@ impl PaymentAttemptInterface for MockDb { Err(StorageError::MockDbError)? } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn get_total_count_of_filtered_payment_attempts( &self, _merchant_id: &common_utils::id_type::MerchantId, @@ -51,6 +58,7 @@ impl PaymentAttemptInterface for MockDb { Err(StorageError::MockDbError)? } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn find_payment_attempt_by_attempt_id_merchant_id( &self, _attempt_id: &str, @@ -61,6 +69,20 @@ impl PaymentAttemptInterface for MockDb { Err(StorageError::MockDbError)? } + #[cfg(all(feature = "v2", feature = "payment_v2"))] + async fn find_payment_attempt_by_attempt_id_merchant_id( + &self, + _key_manager_state: &KeyManagerState, + _merchant_key_store: &MerchantKeyStore, + _attempt_id: &str, + _merchant_id: &common_utils::id_type::MerchantId, + _storage_scheme: storage_enums::MerchantStorageScheme, + ) -> CustomResult { + // [#172]: Implement function for `MockDb` + Err(StorageError::MockDbError)? + } + + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn find_payment_attempt_by_preprocessing_id_merchant_id( &self, _preprocessing_id: &str, @@ -71,6 +93,7 @@ impl PaymentAttemptInterface for MockDb { Err(StorageError::MockDbError)? } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn find_payment_attempt_by_merchant_id_connector_txn_id( &self, _merchant_id: &common_utils::id_type::MerchantId, @@ -81,6 +104,7 @@ impl PaymentAttemptInterface for MockDb { Err(StorageError::MockDbError)? } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn find_attempts_by_merchant_id_payment_id( &self, _merchant_id: &common_utils::id_type::MerchantId, @@ -91,6 +115,7 @@ impl PaymentAttemptInterface for MockDb { Err(StorageError::MockDbError)? } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] #[allow(clippy::panic)] async fn insert_payment_attempt( &self, @@ -168,6 +193,20 @@ impl PaymentAttemptInterface for MockDb { Ok(payment_attempt) } + #[cfg(all(feature = "v2", feature = "payment_v2"))] + #[allow(clippy::panic)] + async fn insert_payment_attempt( + &self, + _key_manager_state: &KeyManagerState, + _merchant_key_store: &MerchantKeyStore, + _payment_attempt: PaymentAttempt, + _storage_scheme: storage_enums::MerchantStorageScheme, + ) -> CustomResult { + // [#172]: Implement function for `MockDb` + Err(StorageError::MockDbError)? + } + + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] // safety: only used for testing #[allow(clippy::unwrap_used)] async fn update_payment_attempt_with_attempt_id( @@ -192,6 +231,20 @@ impl PaymentAttemptInterface for MockDb { Ok(item.clone()) } + #[cfg(all(feature = "v2", feature = "payment_v2"))] + async fn update_payment_attempt_with_attempt_id( + &self, + _key_manager_state: &KeyManagerState, + _merchant_key_store: &MerchantKeyStore, + _this: PaymentAttempt, + _payment_attempt: PaymentAttemptUpdate, + _storage_scheme: storage_enums::MerchantStorageScheme, + ) -> CustomResult { + // [#172]: Implement function for `MockDb` + Err(StorageError::MockDbError)? + } + + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] async fn find_payment_attempt_by_connector_transaction_id_payment_id_merchant_id( &self, _connector_transaction_id: &str, @@ -203,6 +256,7 @@ impl PaymentAttemptInterface for MockDb { Err(StorageError::MockDbError)? } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] // safety: only used for testing #[allow(clippy::unwrap_used)] async fn find_payment_attempt_last_successful_attempt_by_payment_id_merchant_id( @@ -222,6 +276,8 @@ impl PaymentAttemptInterface for MockDb { .cloned() .unwrap()) } + + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] #[allow(clippy::unwrap_used)] async fn find_payment_attempt_last_successful_or_partially_captured_attempt_by_payment_id_merchant_id( &self, diff --git a/crates/storage_impl/src/payments/payment_attempt.rs b/crates/storage_impl/src/payments/payment_attempt.rs index 85fe2b22d3..d1df686165 100644 --- a/crates/storage_impl/src/payments/payment_attempt.rs +++ b/crates/storage_impl/src/payments/payment_attempt.rs @@ -1,5 +1,7 @@ use api_models::enums::{AuthenticationType, Connector, PaymentMethod, PaymentMethodType}; -use common_utils::{errors::CustomResult, fallback_reverse_lookup_not_found, types::MinorUnit}; +#[cfg(all(feature = "v2", feature = "payment_v2"))] +use common_utils::types::keymanager::KeyManagerState; +use common_utils::{errors::CustomResult, fallback_reverse_lookup_not_found}; use diesel_models::{ enums::{ MandateAmountData as DieselMandateAmountData, MandateDataType as DieselMandateType, @@ -25,6 +27,10 @@ use hyperswitch_domain_models::{ PaymentIntent, }, }; +#[cfg(all(feature = "v2", feature = "payment_v2"))] +use hyperswitch_domain_models::{ + behaviour::ReverseConversion, merchant_key_store::MerchantKeyStore, +}; use redis_interface::HsetnxReply; use router_env::{instrument, tracing}; @@ -39,6 +45,7 @@ use crate::{ #[async_trait::async_trait] impl PaymentAttemptInterface for RouterStore { + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] #[instrument(skip_all)] async fn insert_payment_attempt( &self, @@ -57,6 +64,36 @@ impl PaymentAttemptInterface for RouterStore { .map(PaymentAttempt::from_storage_model) } + #[cfg(all(feature = "v2", feature = "payment_v2"))] + #[instrument(skip_all)] + async fn insert_payment_attempt( + &self, + key_manager_state: &KeyManagerState, + merchant_key_store: &MerchantKeyStore, + payment_attempt: PaymentAttempt, + _storage_scheme: MerchantStorageScheme, + ) -> CustomResult { + let conn = pg_connection_write(self).await?; + payment_attempt + .construct_new() + .await + .change_context(errors::StorageError::EncryptionError)? + .insert(&conn) + .await + .map_err(|error| { + let new_error = diesel_error_to_data_error(error.current_context()); + error.change_context(new_error) + })? + .convert( + key_manager_state, + merchant_key_store.key.get_inner(), + merchant_key_store.merchant_id.clone().into(), + ) + .await + .change_context(errors::StorageError::DecryptionError) + } + + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] #[instrument(skip_all)] async fn update_payment_attempt_with_attempt_id( &self, @@ -75,6 +112,40 @@ impl PaymentAttemptInterface for RouterStore { .map(PaymentAttempt::from_storage_model) } + #[cfg(all(feature = "v2", feature = "payment_v2"))] + #[instrument(skip_all)] + async fn update_payment_attempt_with_attempt_id( + &self, + key_manager_state: &KeyManagerState, + merchant_key_store: &MerchantKeyStore, + this: PaymentAttempt, + payment_attempt: PaymentAttemptUpdate, + _storage_scheme: MerchantStorageScheme, + ) -> CustomResult { + let conn = pg_connection_write(self).await?; + + Conversion::convert(this) + .await + .change_context(errors::StorageError::EncryptionError)? + .update_with_attempt_id( + &conn, + diesel_models::PaymentAttemptUpdateInternal::from(payment_attempt), + ) + .await + .map_err(|error| { + let new_error = diesel_error_to_data_error(error.current_context()); + error.change_context(new_error) + })? + .convert( + key_manager_state, + merchant_key_store.key.get_inner(), + merchant_key_store.merchant_id.clone().into(), + ) + .await + .change_context(errors::StorageError::DecryptionError) + } + + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] #[instrument(skip_all)] async fn find_payment_attempt_by_connector_transaction_id_payment_id_merchant_id( &self, @@ -98,6 +169,7 @@ impl PaymentAttemptInterface for RouterStore { .map(PaymentAttempt::from_storage_model) } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] #[instrument(skip_all)] async fn find_payment_attempt_last_successful_attempt_by_payment_id_merchant_id( &self, @@ -119,6 +191,7 @@ impl PaymentAttemptInterface for RouterStore { .map(PaymentAttempt::from_storage_model) } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] #[instrument(skip_all)] async fn find_payment_attempt_last_successful_or_partially_captured_attempt_by_payment_id_merchant_id( &self, @@ -140,6 +213,7 @@ impl PaymentAttemptInterface for RouterStore { .map(PaymentAttempt::from_storage_model) } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] #[instrument(skip_all)] async fn find_payment_attempt_by_merchant_id_connector_txn_id( &self, @@ -161,6 +235,7 @@ impl PaymentAttemptInterface for RouterStore { .map(PaymentAttempt::from_storage_model) } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] #[instrument(skip_all)] async fn find_payment_attempt_by_payment_id_merchant_id_attempt_id( &self, @@ -185,6 +260,7 @@ impl PaymentAttemptInterface for RouterStore { .map(PaymentAttempt::from_storage_model) } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] #[instrument(skip_all)] async fn get_filters_for_payments( &self, @@ -194,7 +270,7 @@ impl PaymentAttemptInterface for RouterStore { ) -> CustomResult { let conn = pg_connection_read(self).await?; let intents = futures::future::try_join_all(pi.iter().cloned().map(|pi| async { - pi.convert() + Conversion::convert(pi) .await .change_context(errors::StorageError::EncryptionError) })) @@ -225,6 +301,7 @@ impl PaymentAttemptInterface for RouterStore { ) } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] #[instrument(skip_all)] async fn find_payment_attempt_by_preprocessing_id_merchant_id( &self, @@ -247,6 +324,7 @@ impl PaymentAttemptInterface for RouterStore { .map(PaymentAttempt::from_storage_model) } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] #[instrument(skip_all)] async fn find_attempts_by_merchant_id_payment_id( &self, @@ -268,6 +346,7 @@ impl PaymentAttemptInterface for RouterStore { }) } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] #[instrument(skip_all)] async fn find_payment_attempt_by_attempt_id_merchant_id( &self, @@ -286,6 +365,34 @@ impl PaymentAttemptInterface for RouterStore { .map(PaymentAttempt::from_storage_model) } + #[cfg(all(feature = "v2", feature = "payment_v2"))] + #[instrument(skip_all)] + async fn find_payment_attempt_by_attempt_id_merchant_id( + &self, + key_manager_state: &KeyManagerState, + merchant_key_store: &MerchantKeyStore, + attempt_id: &str, + merchant_id: &common_utils::id_type::MerchantId, + _storage_scheme: MerchantStorageScheme, + ) -> CustomResult { + let conn = pg_connection_read(self).await?; + + DieselPaymentAttempt::find_by_merchant_id_attempt_id(&conn, merchant_id, attempt_id) + .await + .map_err(|er| { + let new_err = diesel_error_to_data_error(er.current_context()); + er.change_context(new_err) + })? + .convert( + key_manager_state, + merchant_key_store.key.get_inner(), + merchant_key_store.merchant_id.clone().into(), + ) + .await + .change_context(errors::StorageError::DecryptionError) + } + + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] #[instrument(skip_all)] async fn get_total_count_of_filtered_payment_attempts( &self, @@ -332,6 +439,7 @@ impl PaymentAttemptInterface for RouterStore { #[async_trait::async_trait] impl PaymentAttemptInterface for KVRouterStore { + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] #[instrument(skip_all)] async fn insert_payment_attempt( &self, @@ -480,6 +588,27 @@ impl PaymentAttemptInterface for KVRouterStore { } } + #[cfg(all(feature = "v2", feature = "payment_v2"))] + #[instrument(skip_all)] + async fn insert_payment_attempt( + &self, + key_manager_state: &KeyManagerState, + merchant_key_store: &MerchantKeyStore, + payment_attempt: PaymentAttempt, + storage_scheme: MerchantStorageScheme, + ) -> error_stack::Result { + // Ignoring storage scheme for v2 implementation + self.router_store + .insert_payment_attempt( + key_manager_state, + merchant_key_store, + payment_attempt, + storage_scheme, + ) + .await + } + + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] #[instrument(skip_all)] async fn update_payment_attempt_with_attempt_id( &self, @@ -603,6 +732,29 @@ impl PaymentAttemptInterface for KVRouterStore { } } + #[cfg(all(feature = "v2", feature = "payment_v2"))] + #[instrument(skip_all)] + async fn update_payment_attempt_with_attempt_id( + &self, + key_manager_state: &KeyManagerState, + merchant_key_store: &MerchantKeyStore, + this: PaymentAttempt, + payment_attempt: PaymentAttemptUpdate, + storage_scheme: MerchantStorageScheme, + ) -> error_stack::Result { + // Ignoring storage scheme for v2 implementation + self.router_store + .update_payment_attempt_with_attempt_id( + key_manager_state, + merchant_key_store, + this, + payment_attempt, + storage_scheme, + ) + .await + } + + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] #[instrument(skip_all)] async fn find_payment_attempt_by_connector_transaction_id_payment_id_merchant_id( &self, @@ -662,6 +814,7 @@ impl PaymentAttemptInterface for KVRouterStore { } } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] #[instrument(skip_all)] async fn find_payment_attempt_last_successful_attempt_by_payment_id_merchant_id( &self, @@ -720,6 +873,7 @@ impl PaymentAttemptInterface for KVRouterStore { } } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] #[instrument(skip_all)] async fn find_payment_attempt_last_successful_or_partially_captured_attempt_by_payment_id_merchant_id( &self, @@ -781,6 +935,7 @@ impl PaymentAttemptInterface for KVRouterStore { } } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] #[instrument(skip_all)] async fn find_payment_attempt_by_merchant_id_connector_txn_id( &self, @@ -849,6 +1004,7 @@ impl PaymentAttemptInterface for KVRouterStore { } } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] #[instrument(skip_all)] async fn find_payment_attempt_by_payment_id_merchant_id_attempt_id( &self, @@ -902,6 +1058,7 @@ impl PaymentAttemptInterface for KVRouterStore { } } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] #[instrument(skip_all)] async fn find_payment_attempt_by_attempt_id_merchant_id( &self, @@ -967,6 +1124,29 @@ impl PaymentAttemptInterface for KVRouterStore { } } + #[cfg(all(feature = "v2", feature = "payment_v2"))] + #[instrument(skip_all)] + async fn find_payment_attempt_by_attempt_id_merchant_id( + &self, + key_manager_state: &KeyManagerState, + merchant_key_store: &MerchantKeyStore, + attempt_id: &str, + merchant_id: &common_utils::id_type::MerchantId, + storage_scheme: MerchantStorageScheme, + ) -> error_stack::Result { + // Ignoring storage scheme for v2 implementation + self.router_store + .find_payment_attempt_by_attempt_id_merchant_id( + key_manager_state, + merchant_key_store, + attempt_id, + merchant_id, + storage_scheme, + ) + .await + } + + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] #[instrument(skip_all)] async fn find_payment_attempt_by_preprocessing_id_merchant_id( &self, @@ -1035,6 +1215,7 @@ impl PaymentAttemptInterface for KVRouterStore { } } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] #[instrument(skip_all)] async fn find_attempts_by_merchant_id_payment_id( &self, @@ -1084,6 +1265,7 @@ impl PaymentAttemptInterface for KVRouterStore { } } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] #[instrument(skip_all)] async fn get_filters_for_payments( &self, @@ -1096,6 +1278,7 @@ impl PaymentAttemptInterface for KVRouterStore { .await } + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "payment_v2")))] #[instrument(skip_all)] async fn get_total_count_of_filtered_payment_attempts( &self, @@ -1130,7 +1313,7 @@ impl DataModelExt for MandateAmountData { fn to_storage_model(self) -> Self::StorageModel { DieselMandateAmountData { - amount: self.amount.get_amount_as_i64(), + amount: self.amount, currency: self.currency, start_date: self.start_date, end_date: self.end_date, @@ -1140,7 +1323,7 @@ impl DataModelExt for MandateAmountData { fn from_storage_model(storage_model: Self::StorageModel) -> Self { Self { - amount: MinorUnit::new(storage_model.amount), + amount: storage_model.amount, currency: storage_model.currency, start_date: storage_model.start_date, end_date: storage_model.end_date, @@ -1198,19 +1381,15 @@ impl DataModelExt for PaymentAttempt { merchant_id: self.merchant_id, attempt_id: self.attempt_id, status: self.status, - amount: self.amount.get_amount_as_i64(), - net_amount: Some(self.net_amount.get_amount_as_i64()), + amount: self.amount, + net_amount: Some(self.net_amount), currency: self.currency, save_to_locker: self.save_to_locker, connector: self.connector, error_message: self.error_message, - offer_amount: self - .offer_amount - .map(|offer_amt| offer_amt.get_amount_as_i64()), - surcharge_amount: self - .surcharge_amount - .map(|surcharge_amt| surcharge_amt.get_amount_as_i64()), - tax_amount: self.tax_amount.map(|tax_amt| tax_amt.get_amount_as_i64()), + offer_amount: self.offer_amount, + surcharge_amount: self.surcharge_amount, + tax_amount: self.tax_amount, payment_method_id: self.payment_method_id, payment_method: self.payment_method, connector_transaction_id: self.connector_transaction_id, @@ -1222,9 +1401,7 @@ impl DataModelExt for PaymentAttempt { modified_at: self.modified_at, last_synced: self.last_synced, cancellation_reason: self.cancellation_reason, - amount_to_capture: self - .amount_to_capture - .map(|capture_amt| capture_amt.get_amount_as_i64()), + amount_to_capture: self.amount_to_capture, mandate_id: self.mandate_id, browser_info: self.browser_info, error_code: self.error_code, @@ -1249,7 +1426,7 @@ impl DataModelExt for PaymentAttempt { error_reason: self.error_reason, multiple_capture_count: self.multiple_capture_count, connector_response_reference_id: self.connector_response_reference_id, - amount_capturable: self.amount_capturable.get_amount_as_i64(), + amount_capturable: self.amount_capturable, updated_by: self.updated_by, authentication_data: self.authentication_data, encoded_data: self.encoded_data, @@ -1276,19 +1453,19 @@ impl DataModelExt for PaymentAttempt { fn from_storage_model(storage_model: Self::StorageModel) -> Self { Self { - net_amount: MinorUnit::new(storage_model.get_or_calculate_net_amount()), + net_amount: storage_model.get_or_calculate_net_amount(), payment_id: storage_model.payment_id, merchant_id: storage_model.merchant_id, attempt_id: storage_model.attempt_id, status: storage_model.status, - amount: MinorUnit::new(storage_model.amount), + amount: storage_model.amount, currency: storage_model.currency, save_to_locker: storage_model.save_to_locker, connector: storage_model.connector, error_message: storage_model.error_message, - offer_amount: storage_model.offer_amount.map(MinorUnit::new), - surcharge_amount: storage_model.surcharge_amount.map(MinorUnit::new), - tax_amount: storage_model.tax_amount.map(MinorUnit::new), + offer_amount: storage_model.offer_amount, + surcharge_amount: storage_model.surcharge_amount, + tax_amount: storage_model.tax_amount, payment_method_id: storage_model.payment_method_id, payment_method: storage_model.payment_method, connector_transaction_id: storage_model.connector_transaction_id, @@ -1300,7 +1477,7 @@ impl DataModelExt for PaymentAttempt { modified_at: storage_model.modified_at, last_synced: storage_model.last_synced, cancellation_reason: storage_model.cancellation_reason, - amount_to_capture: storage_model.amount_to_capture.map(MinorUnit::new), + amount_to_capture: storage_model.amount_to_capture, mandate_id: storage_model.mandate_id, browser_info: storage_model.browser_info, error_code: storage_model.error_code, @@ -1318,7 +1495,7 @@ impl DataModelExt for PaymentAttempt { error_reason: storage_model.error_reason, multiple_capture_count: storage_model.multiple_capture_count, connector_response_reference_id: storage_model.connector_response_reference_id, - amount_capturable: MinorUnit::new(storage_model.amount_capturable), + amount_capturable: storage_model.amount_capturable, updated_by: storage_model.updated_by, authentication_data: storage_model.authentication_data, encoded_data: storage_model.encoded_data, @@ -1356,19 +1533,15 @@ impl DataModelExt for PaymentAttempt { merchant_id: self.merchant_id, attempt_id: self.attempt_id, status: self.status, - amount: self.amount.get_amount_as_i64(), - net_amount: Some(self.net_amount.get_amount_as_i64()), + amount: self.amount, + net_amount: Some(self.net_amount), currency: self.currency, save_to_locker: self.save_to_locker, connector: self.connector, error_message: self.error_message, - offer_amount: self - .offer_amount - .map(|offer_amt| offer_amt.get_amount_as_i64()), - surcharge_amount: self - .surcharge_amount - .map(|surcharge_amt| surcharge_amt.get_amount_as_i64()), - tax_amount: self.tax_amount.map(|tax_amt| tax_amt.get_amount_as_i64()), + offer_amount: self.offer_amount, + surcharge_amount: self.surcharge_amount, + tax_amount: self.tax_amount, payment_method_id: self.payment_method_id, payment_method: self.payment_method, connector_transaction_id: self.connector_transaction_id, @@ -1380,9 +1553,7 @@ impl DataModelExt for PaymentAttempt { modified_at: self.modified_at, last_synced: self.last_synced, cancellation_reason: self.cancellation_reason, - amount_to_capture: self - .amount_to_capture - .map(|capture_amt| capture_amt.get_amount_as_i64()), + amount_to_capture: self.amount_to_capture, mandate_id: self.mandate_id, browser_info: self.browser_info, error_code: self.error_code, @@ -1407,7 +1578,7 @@ impl DataModelExt for PaymentAttempt { error_reason: self.error_reason, multiple_capture_count: self.multiple_capture_count, connector_response_reference_id: self.connector_response_reference_id, - amount_capturable: self.amount_capturable.get_amount_as_i64(), + amount_capturable: self.amount_capturable, updated_by: self.updated_by, authentication_data: self.authentication_data, encoded_data: self.encoded_data, @@ -1434,19 +1605,19 @@ impl DataModelExt for PaymentAttempt { fn from_storage_model(storage_model: Self::StorageModel) -> Self { Self { - net_amount: MinorUnit::new(storage_model.get_or_calculate_net_amount()), + net_amount: storage_model.get_or_calculate_net_amount(), payment_id: storage_model.payment_id, merchant_id: storage_model.merchant_id, attempt_id: storage_model.attempt_id, status: storage_model.status, - amount: MinorUnit::new(storage_model.amount), + amount: storage_model.amount, currency: storage_model.currency, save_to_locker: storage_model.save_to_locker, connector: storage_model.connector, error_message: storage_model.error_message, - offer_amount: storage_model.offer_amount.map(MinorUnit::new), - surcharge_amount: storage_model.surcharge_amount.map(MinorUnit::new), - tax_amount: storage_model.tax_amount.map(MinorUnit::new), + offer_amount: storage_model.offer_amount, + surcharge_amount: storage_model.surcharge_amount, + tax_amount: storage_model.tax_amount, payment_method_id: storage_model.payment_method_id, payment_method: storage_model.payment_method, connector_transaction_id: storage_model.connector_transaction_id, @@ -1458,7 +1629,7 @@ impl DataModelExt for PaymentAttempt { modified_at: storage_model.modified_at, last_synced: storage_model.last_synced, cancellation_reason: storage_model.cancellation_reason, - amount_to_capture: storage_model.amount_to_capture.map(MinorUnit::new), + amount_to_capture: storage_model.amount_to_capture, mandate_id: storage_model.mandate_id, browser_info: storage_model.browser_info, error_code: storage_model.error_code, @@ -1476,7 +1647,7 @@ impl DataModelExt for PaymentAttempt { error_reason: storage_model.error_reason, multiple_capture_count: storage_model.multiple_capture_count, connector_response_reference_id: storage_model.connector_response_reference_id, - amount_capturable: MinorUnit::new(storage_model.amount_capturable), + amount_capturable: storage_model.amount_capturable, updated_by: storage_model.updated_by, authentication_data: storage_model.authentication_data, encoded_data: storage_model.encoded_data, @@ -1509,23 +1680,19 @@ impl DataModelExt for PaymentAttemptNew { fn to_storage_model(self) -> Self::StorageModel { DieselPaymentAttemptNew { - net_amount: Some(self.net_amount.get_amount_as_i64()), + net_amount: Some(self.net_amount), payment_id: self.payment_id, merchant_id: self.merchant_id, attempt_id: self.attempt_id, status: self.status, - amount: self.amount.get_amount_as_i64(), + amount: self.amount, currency: self.currency, save_to_locker: self.save_to_locker, connector: self.connector, error_message: self.error_message, - offer_amount: self - .offer_amount - .map(|offer_amt| offer_amt.get_amount_as_i64()), - surcharge_amount: self - .surcharge_amount - .map(|surcharge_amt| surcharge_amt.get_amount_as_i64()), - tax_amount: self.tax_amount.map(|tax_amt| tax_amt.get_amount_as_i64()), + offer_amount: self.offer_amount, + surcharge_amount: self.surcharge_amount, + tax_amount: self.tax_amount, payment_method_id: self.payment_method_id, payment_method: self.payment_method, capture_method: self.capture_method, @@ -1538,9 +1705,7 @@ impl DataModelExt for PaymentAttemptNew { .unwrap_or_else(common_utils::date_time::now), last_synced: self.last_synced, cancellation_reason: self.cancellation_reason, - amount_to_capture: self - .amount_to_capture - .map(|capture_amt| capture_amt.get_amount_as_i64()), + amount_to_capture: self.amount_to_capture, mandate_id: self.mandate_id, browser_info: self.browser_info, payment_token: self.payment_token, @@ -1565,7 +1730,7 @@ impl DataModelExt for PaymentAttemptNew { error_reason: self.error_reason, connector_response_reference_id: self.connector_response_reference_id, multiple_capture_count: self.multiple_capture_count, - amount_capturable: self.amount_capturable.get_amount_as_i64(), + amount_capturable: self.amount_capturable, updated_by: self.updated_by, authentication_data: self.authentication_data, encoded_data: self.encoded_data, @@ -1592,19 +1757,19 @@ impl DataModelExt for PaymentAttemptNew { fn from_storage_model(storage_model: Self::StorageModel) -> Self { Self { - net_amount: MinorUnit::new(storage_model.get_or_calculate_net_amount()), + net_amount: storage_model.get_or_calculate_net_amount(), payment_id: storage_model.payment_id, merchant_id: storage_model.merchant_id, attempt_id: storage_model.attempt_id, status: storage_model.status, - amount: MinorUnit::new(storage_model.amount), + amount: storage_model.amount, currency: storage_model.currency, save_to_locker: storage_model.save_to_locker, connector: storage_model.connector, error_message: storage_model.error_message, - offer_amount: storage_model.offer_amount.map(MinorUnit::new), - surcharge_amount: storage_model.surcharge_amount.map(MinorUnit::new), - tax_amount: storage_model.tax_amount.map(MinorUnit::new), + offer_amount: storage_model.offer_amount, + surcharge_amount: storage_model.surcharge_amount, + tax_amount: storage_model.tax_amount, payment_method_id: storage_model.payment_method_id, payment_method: storage_model.payment_method, capture_method: storage_model.capture_method, @@ -1615,7 +1780,7 @@ impl DataModelExt for PaymentAttemptNew { modified_at: Some(storage_model.modified_at), last_synced: storage_model.last_synced, cancellation_reason: storage_model.cancellation_reason, - amount_to_capture: storage_model.amount_to_capture.map(MinorUnit::new), + amount_to_capture: storage_model.amount_to_capture, mandate_id: storage_model.mandate_id, browser_info: storage_model.browser_info, payment_token: storage_model.payment_token, @@ -1633,7 +1798,7 @@ impl DataModelExt for PaymentAttemptNew { error_reason: storage_model.error_reason, connector_response_reference_id: storage_model.connector_response_reference_id, multiple_capture_count: storage_model.multiple_capture_count, - amount_capturable: MinorUnit::new(storage_model.amount_capturable), + amount_capturable: storage_model.amount_capturable, updated_by: storage_model.updated_by, authentication_data: storage_model.authentication_data, encoded_data: storage_model.encoded_data, @@ -1685,7 +1850,7 @@ impl DataModelExt for PaymentAttemptUpdate { payment_method_billing_address_id, updated_by, } => DieselPaymentAttemptUpdate::Update { - amount: amount.get_amount_as_i64(), + amount, currency, status, authentication_type, @@ -1695,12 +1860,10 @@ impl DataModelExt for PaymentAttemptUpdate { payment_method_type, payment_experience, business_sub_label, - amount_to_capture: amount_to_capture - .map(|capture_amt| capture_amt.get_amount_as_i64()), + amount_to_capture, capture_method, - surcharge_amount: surcharge_amount - .map(|surcharge_amt| surcharge_amt.get_amount_as_i64()), - tax_amount: tax_amount.map(|tax_amt| tax_amt.get_amount_as_i64()), + surcharge_amount, + tax_amount, fingerprint_id, payment_method_billing_address_id, updated_by, @@ -1718,11 +1881,9 @@ impl DataModelExt for PaymentAttemptUpdate { payment_token, connector, straight_through_algorithm, - amount_capturable: amount_capturable - .map(|amount_capturable| amount_capturable.get_amount_as_i64()), - surcharge_amount: surcharge_amount - .map(|surcharge_amt| surcharge_amt.get_amount_as_i64()), - tax_amount: tax_amount.map(|tax_amt| tax_amt.get_amount_as_i64()), + amount_capturable, + surcharge_amount, + tax_amount, updated_by, merchant_connector_id, }, @@ -1785,7 +1946,7 @@ impl DataModelExt for PaymentAttemptUpdate { shipping_cost, order_tax_amount, } => DieselPaymentAttemptUpdate::ConfirmUpdate { - amount: amount.get_amount_as_i64(), + amount, currency, status, authentication_type, @@ -1801,11 +1962,9 @@ impl DataModelExt for PaymentAttemptUpdate { straight_through_algorithm, error_code, error_message, - amount_capturable: amount_capturable - .map(|capture_amt| capture_amt.get_amount_as_i64()), - surcharge_amount: surcharge_amount - .map(|surcharge_amt| surcharge_amt.get_amount_as_i64()), - tax_amount: tax_amount.map(|tax_amt| tax_amt.get_amount_as_i64()), + amount_capturable, + surcharge_amount, + tax_amount, fingerprint_id, updated_by, merchant_connector_id: connector_id, @@ -1863,8 +2022,7 @@ impl DataModelExt for PaymentAttemptUpdate { error_message, error_reason, connector_response_reference_id, - amount_capturable: amount_capturable - .map(|capture_amt| capture_amt.get_amount_as_i64()), + amount_capturable, updated_by, authentication_data, encoded_data, @@ -1916,8 +2074,7 @@ impl DataModelExt for PaymentAttemptUpdate { error_code, error_message, error_reason, - amount_capturable: amount_capturable - .map(|capture_amt| capture_amt.get_amount_as_i64()), + amount_capturable, updated_by, unified_code, unified_message, @@ -1932,8 +2089,7 @@ impl DataModelExt for PaymentAttemptUpdate { } => DieselPaymentAttemptUpdate::CaptureUpdate { multiple_capture_count, updated_by, - amount_to_capture: amount_to_capture - .map(|capture_amt| capture_amt.get_amount_as_i64()), + amount_to_capture, }, Self::PreprocessingUpdate { status, @@ -1969,7 +2125,7 @@ impl DataModelExt for PaymentAttemptUpdate { updated_by, } => DieselPaymentAttemptUpdate::AmountToCaptureUpdate { status, - amount_capturable: amount_capturable.get_amount_as_i64(), + amount_capturable, updated_by, }, Self::ConnectorResponse { @@ -1991,8 +2147,8 @@ impl DataModelExt for PaymentAttemptUpdate { amount, amount_capturable, } => DieselPaymentAttemptUpdate::IncrementalAuthorizationAmountUpdate { - amount: amount.get_amount_as_i64(), - amount_capturable: amount_capturable.get_amount_as_i64(), + amount, + amount_capturable, }, Self::AuthenticationUpdate { status, @@ -2050,7 +2206,7 @@ impl DataModelExt for PaymentAttemptUpdate { updated_by, payment_method_billing_address_id, } => Self::Update { - amount: MinorUnit::new(amount), + amount, currency, status, authentication_type, @@ -2060,10 +2216,10 @@ impl DataModelExt for PaymentAttemptUpdate { payment_method_type, payment_experience, business_sub_label, - amount_to_capture: amount_to_capture.map(MinorUnit::new), + amount_to_capture, capture_method, - surcharge_amount: surcharge_amount.map(MinorUnit::new), - tax_amount: tax_amount.map(MinorUnit::new), + surcharge_amount, + tax_amount, fingerprint_id, payment_method_billing_address_id, updated_by, @@ -2081,9 +2237,9 @@ impl DataModelExt for PaymentAttemptUpdate { payment_token, connector, straight_through_algorithm, - amount_capturable: amount_capturable.map(MinorUnit::new), - surcharge_amount: surcharge_amount.map(MinorUnit::new), - tax_amount: tax_amount.map(MinorUnit::new), + amount_capturable, + surcharge_amount, + tax_amount, updated_by, merchant_connector_id: connector_id, }, @@ -2128,7 +2284,7 @@ impl DataModelExt for PaymentAttemptUpdate { shipping_cost, order_tax_amount, } => Self::ConfirmUpdate { - amount: MinorUnit::new(amount), + amount, currency, status, authentication_type, @@ -2144,9 +2300,9 @@ impl DataModelExt for PaymentAttemptUpdate { straight_through_algorithm, error_code, error_message, - amount_capturable: amount_capturable.map(MinorUnit::new), - surcharge_amount: surcharge_amount.map(MinorUnit::new), - tax_amount: tax_amount.map(MinorUnit::new), + amount_capturable, + surcharge_amount, + tax_amount, fingerprint_id, updated_by, merchant_connector_id: connector_id, @@ -2222,7 +2378,7 @@ impl DataModelExt for PaymentAttemptUpdate { error_message, error_reason, connector_response_reference_id, - amount_capturable: amount_capturable.map(MinorUnit::new), + amount_capturable, updated_by, authentication_data, encoded_data, @@ -2274,7 +2430,7 @@ impl DataModelExt for PaymentAttemptUpdate { error_code, error_message, error_reason, - amount_capturable: amount_capturable.map(MinorUnit::new), + amount_capturable, updated_by, unified_code, unified_message, @@ -2287,7 +2443,7 @@ impl DataModelExt for PaymentAttemptUpdate { multiple_capture_count, updated_by, } => Self::CaptureUpdate { - amount_to_capture: amount_to_capture.map(MinorUnit::new), + amount_to_capture, multiple_capture_count, updated_by, }, @@ -2325,7 +2481,7 @@ impl DataModelExt for PaymentAttemptUpdate { updated_by, } => Self::AmountToCaptureUpdate { status, - amount_capturable: MinorUnit::new(amount_capturable), + amount_capturable, updated_by, }, DieselPaymentAttemptUpdate::ConnectorResponse { @@ -2347,8 +2503,8 @@ impl DataModelExt for PaymentAttemptUpdate { amount, amount_capturable, } => Self::IncrementalAuthorizationAmountUpdate { - amount: MinorUnit::new(amount), - amount_capturable: MinorUnit::new(amount_capturable), + amount, + amount_capturable, }, DieselPaymentAttemptUpdate::AuthenticationUpdate { status,