diff --git a/crates/diesel_models/src/payment_method.rs b/crates/diesel_models/src/payment_method.rs index d9c7a66a6b2..16e8ddeb7d5 100644 --- a/crates/diesel_models/src/payment_method.rs +++ b/crates/diesel_models/src/payment_method.rs @@ -96,8 +96,13 @@ pub struct TokenizeCoreWorkflow { #[derive(Debug, Serialize, Deserialize)] pub enum PaymentMethodUpdate { - MetadataUpdate { + MetadataUpdateAndLastUsed { metadata: Option, + last_used_at: PrimitiveDateTime, + }, + UpdatePaymentMethodDataAndLastUsed { + payment_method_data: Option, + last_used_at: PrimitiveDateTime, }, PaymentMethodDataUpdate { payment_method_data: Option, @@ -191,10 +196,13 @@ impl PaymentMethodUpdateInternal { impl From for PaymentMethodUpdateInternal { fn from(payment_method_update: PaymentMethodUpdate) -> Self { match payment_method_update { - PaymentMethodUpdate::MetadataUpdate { metadata } => Self { + PaymentMethodUpdate::MetadataUpdateAndLastUsed { + metadata, + last_used_at, + } => Self { metadata, payment_method_data: None, - last_used_at: None, + last_used_at: Some(last_used_at), network_transaction_id: None, status: None, locker_id: None, @@ -232,6 +240,22 @@ impl From for PaymentMethodUpdateInternal { payment_method_issuer: None, payment_method_type: None, }, + PaymentMethodUpdate::UpdatePaymentMethodDataAndLastUsed { + payment_method_data, + last_used_at, + } => Self { + metadata: None, + payment_method_data, + last_used_at: Some(last_used_at), + network_transaction_id: None, + status: None, + locker_id: None, + payment_method: None, + connector_mandate_details: None, + updated_by: None, + payment_method_issuer: None, + payment_method_type: None, + }, PaymentMethodUpdate::NetworkTransactionIdAndStatusUpdate { network_transaction_id, status, diff --git a/crates/router/src/core/payment_methods/cards.rs b/crates/router/src/core/payment_methods/cards.rs index 53b0063c6ef..04137b53c87 100644 --- a/crates/router/src/core/payment_methods/cards.rs +++ b/crates/router/src/core/payment_methods/cards.rs @@ -1389,14 +1389,31 @@ pub async fn call_to_locker_hs<'a>( Ok(stored_card) } -pub async fn update_payment_method( +pub async fn update_payment_method_metadata_and_last_used( db: &dyn db::StorageInterface, pm: payment_method::PaymentMethod, - pm_metadata: serde_json::Value, + pm_metadata: Option, + storage_scheme: MerchantStorageScheme, +) -> errors::CustomResult<(), errors::VaultError> { + let pm_update = payment_method::PaymentMethodUpdate::MetadataUpdateAndLastUsed { + metadata: pm_metadata, + last_used_at: common_utils::date_time::now(), + }; + db.update_payment_method(pm, pm_update, storage_scheme) + .await + .change_context(errors::VaultError::UpdateInPaymentMethodDataTableFailed)?; + Ok(()) +} + +pub async fn update_payment_method_and_last_used( + db: &dyn db::StorageInterface, + pm: payment_method::PaymentMethod, + payment_method_update: Option, storage_scheme: MerchantStorageScheme, ) -> errors::CustomResult<(), errors::VaultError> { - let pm_update = payment_method::PaymentMethodUpdate::MetadataUpdate { - metadata: Some(pm_metadata), + let pm_update = payment_method::PaymentMethodUpdate::UpdatePaymentMethodDataAndLastUsed { + payment_method_data: payment_method_update, + last_used_at: common_utils::date_time::now(), }; db.update_payment_method(pm, pm_update, storage_scheme) .await diff --git a/crates/router/src/core/payments/operations/payment_response.rs b/crates/router/src/core/payments/operations/payment_response.rs index c4e4cb694e6..8fb0964da6e 100644 --- a/crates/router/src/core/payments/operations/payment_response.rs +++ b/crates/router/src/core/payments/operations/payment_response.rs @@ -114,9 +114,14 @@ impl PostUpdateTracker, types::PaymentsAuthor .get_payment_method_billing() .and_then(|billing_details| billing_details.address.as_ref()) .and_then(|address| address.get_optional_full_name()); + let mut should_avoid_saving = false; if let Some(payment_method_info) = &payment_data.payment_method_info { if payment_data.payment_intent.off_session.is_none() && resp.response.is_ok() { + should_avoid_saving = resp.request.payment_method_type + == Some(enums::PaymentMethodType::ApplePay) + || resp.request.payment_method_type + == Some(enums::PaymentMethodType::GooglePay); payment_methods::cards::update_last_used_at( payment_method_info, state, @@ -179,6 +184,12 @@ impl PostUpdateTracker, types::PaymentsAuthor let (payment_method_id, _payment_method_status) = save_payment_call_future.await?; payment_data.payment_attempt.payment_method_id = payment_method_id; Ok(()) + } else if should_avoid_saving { + if let Some(pm_info) = &payment_data.payment_method_info { + payment_data.payment_attempt.payment_method_id = + Some(pm_info.payment_method_id.clone()); + }; + Ok(()) } else { // Save card flow let save_payment_data = tokenization::SavePaymentMethodData::from(resp); diff --git a/crates/router/src/core/payments/tokenization.rs b/crates/router/src/core/payments/tokenization.rs index 161a9a43532..619d74549e7 100644 --- a/crates/router/src/core/payments/tokenization.rs +++ b/crates/router/src/core/payments/tokenization.rs @@ -269,20 +269,15 @@ where pm.metadata.as_ref(), connector_token, )?; - if let Some(metadata) = pm_metadata { - payment_methods::cards::update_payment_method( - db, - pm.clone(), - metadata, - merchant_account.storage_scheme, - ) - .await - .change_context( - errors::ApiErrorResponse::InternalServerError, - ) - .attach_printable("Failed to add payment method in db")?; - }; - // update if its a off-session mit payment + payment_methods::cards::update_payment_method_metadata_and_last_used( + db, + pm.clone(), + pm_metadata, + merchant_account.storage_scheme, + ) + .await + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Failed to add payment method in db")?; if check_for_mit_mandates { let connector_mandate_details = update_connector_mandate_details_in_payment_method( @@ -511,14 +506,10 @@ where ) .await; - let pm_update = - storage::PaymentMethodUpdate::PaymentMethodDataUpdate { - payment_method_data: pm_data_encrypted, - }; - - db.update_payment_method( + payment_methods::cards::update_payment_method_and_last_used( + db, existing_pm, - pm_update, + pm_data_encrypted, merchant_account.storage_scheme, ) .await @@ -528,7 +519,7 @@ where } }, None => { - let customer_saved_pm_id_option = if payment_method_type + let customer_saved_pm_option = if payment_method_type == Some(api_models::enums::PaymentMethodType::ApplePay) || payment_method_type == Some(api_models::enums::PaymentMethodType::GooglePay) @@ -547,7 +538,7 @@ where .find(|payment_method| { payment_method.payment_method_type == payment_method_type }) - .map(|pm| pm.payment_method_id.clone())), + .cloned()), Err(error) => { if error.current_context().is_db_not_found() { Ok(None) @@ -566,8 +557,18 @@ where Ok(None) }?; - if let Some(customer_saved_pm_id) = customer_saved_pm_id_option { - resp.payment_method_id = customer_saved_pm_id; + if let Some(customer_saved_pm) = customer_saved_pm_option { + payment_methods::cards::update_last_used_at( + &customer_saved_pm, + state, + merchant_account.storage_scheme, + ) + .await + .map_err(|e| { + logger::error!("Failed to update last used at: {:?}", e); + }) + .ok(); + resp.payment_method_id = customer_saved_pm.payment_method_id; } else { let pm_metadata = create_payment_method_metadata(None, connector_token)?;