mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-03 21:37:41 +08:00
fix(router): update last used when the customer acceptance is passed in the recurring payment (#5116)
This commit is contained in:
@ -96,8 +96,13 @@ pub struct TokenizeCoreWorkflow {
|
|||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub enum PaymentMethodUpdate {
|
pub enum PaymentMethodUpdate {
|
||||||
MetadataUpdate {
|
MetadataUpdateAndLastUsed {
|
||||||
metadata: Option<serde_json::Value>,
|
metadata: Option<serde_json::Value>,
|
||||||
|
last_used_at: PrimitiveDateTime,
|
||||||
|
},
|
||||||
|
UpdatePaymentMethodDataAndLastUsed {
|
||||||
|
payment_method_data: Option<Encryption>,
|
||||||
|
last_used_at: PrimitiveDateTime,
|
||||||
},
|
},
|
||||||
PaymentMethodDataUpdate {
|
PaymentMethodDataUpdate {
|
||||||
payment_method_data: Option<Encryption>,
|
payment_method_data: Option<Encryption>,
|
||||||
@ -191,10 +196,13 @@ impl PaymentMethodUpdateInternal {
|
|||||||
impl From<PaymentMethodUpdate> for PaymentMethodUpdateInternal {
|
impl From<PaymentMethodUpdate> for PaymentMethodUpdateInternal {
|
||||||
fn from(payment_method_update: PaymentMethodUpdate) -> Self {
|
fn from(payment_method_update: PaymentMethodUpdate) -> Self {
|
||||||
match payment_method_update {
|
match payment_method_update {
|
||||||
PaymentMethodUpdate::MetadataUpdate { metadata } => Self {
|
PaymentMethodUpdate::MetadataUpdateAndLastUsed {
|
||||||
|
metadata,
|
||||||
|
last_used_at,
|
||||||
|
} => Self {
|
||||||
metadata,
|
metadata,
|
||||||
payment_method_data: None,
|
payment_method_data: None,
|
||||||
last_used_at: None,
|
last_used_at: Some(last_used_at),
|
||||||
network_transaction_id: None,
|
network_transaction_id: None,
|
||||||
status: None,
|
status: None,
|
||||||
locker_id: None,
|
locker_id: None,
|
||||||
@ -232,6 +240,22 @@ impl From<PaymentMethodUpdate> for PaymentMethodUpdateInternal {
|
|||||||
payment_method_issuer: None,
|
payment_method_issuer: None,
|
||||||
payment_method_type: 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 {
|
PaymentMethodUpdate::NetworkTransactionIdAndStatusUpdate {
|
||||||
network_transaction_id,
|
network_transaction_id,
|
||||||
status,
|
status,
|
||||||
|
|||||||
@ -1407,14 +1407,31 @@ pub async fn call_to_locker_hs<'a>(
|
|||||||
Ok(stored_card)
|
Ok(stored_card)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_payment_method(
|
pub async fn update_payment_method_metadata_and_last_used(
|
||||||
db: &dyn db::StorageInterface,
|
db: &dyn db::StorageInterface,
|
||||||
pm: payment_method::PaymentMethod,
|
pm: payment_method::PaymentMethod,
|
||||||
pm_metadata: serde_json::Value,
|
pm_metadata: Option<serde_json::Value>,
|
||||||
storage_scheme: MerchantStorageScheme,
|
storage_scheme: MerchantStorageScheme,
|
||||||
) -> errors::CustomResult<(), errors::VaultError> {
|
) -> errors::CustomResult<(), errors::VaultError> {
|
||||||
let pm_update = payment_method::PaymentMethodUpdate::MetadataUpdate {
|
let pm_update = payment_method::PaymentMethodUpdate::MetadataUpdateAndLastUsed {
|
||||||
metadata: Some(pm_metadata),
|
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<Encryption>,
|
||||||
|
storage_scheme: MerchantStorageScheme,
|
||||||
|
) -> errors::CustomResult<(), errors::VaultError> {
|
||||||
|
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)
|
db.update_payment_method(pm, pm_update, storage_scheme)
|
||||||
.await
|
.await
|
||||||
|
|||||||
@ -114,9 +114,14 @@ impl<F: Send + Clone> PostUpdateTracker<F, PaymentData<F>, types::PaymentsAuthor
|
|||||||
.get_payment_method_billing()
|
.get_payment_method_billing()
|
||||||
.and_then(|billing_details| billing_details.address.as_ref())
|
.and_then(|billing_details| billing_details.address.as_ref())
|
||||||
.and_then(|address| address.get_optional_full_name());
|
.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 let Some(payment_method_info) = &payment_data.payment_method_info {
|
||||||
if payment_data.payment_intent.off_session.is_none() && resp.response.is_ok() {
|
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_methods::cards::update_last_used_at(
|
||||||
payment_method_info,
|
payment_method_info,
|
||||||
state,
|
state,
|
||||||
@ -179,6 +184,12 @@ impl<F: Send + Clone> PostUpdateTracker<F, PaymentData<F>, types::PaymentsAuthor
|
|||||||
let (payment_method_id, _payment_method_status) = save_payment_call_future.await?;
|
let (payment_method_id, _payment_method_status) = save_payment_call_future.await?;
|
||||||
payment_data.payment_attempt.payment_method_id = payment_method_id;
|
payment_data.payment_attempt.payment_method_id = payment_method_id;
|
||||||
Ok(())
|
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 {
|
} else {
|
||||||
// Save card flow
|
// Save card flow
|
||||||
let save_payment_data = tokenization::SavePaymentMethodData::from(resp);
|
let save_payment_data = tokenization::SavePaymentMethodData::from(resp);
|
||||||
|
|||||||
@ -272,20 +272,15 @@ where
|
|||||||
pm.metadata.as_ref(),
|
pm.metadata.as_ref(),
|
||||||
connector_token,
|
connector_token,
|
||||||
)?;
|
)?;
|
||||||
if let Some(metadata) = pm_metadata {
|
payment_methods::cards::update_payment_method_metadata_and_last_used(
|
||||||
payment_methods::cards::update_payment_method(
|
|
||||||
db,
|
db,
|
||||||
pm.clone(),
|
pm.clone(),
|
||||||
metadata,
|
pm_metadata,
|
||||||
merchant_account.storage_scheme,
|
merchant_account.storage_scheme,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.change_context(
|
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||||
errors::ApiErrorResponse::InternalServerError,
|
|
||||||
)
|
|
||||||
.attach_printable("Failed to add payment method in db")?;
|
.attach_printable("Failed to add payment method in db")?;
|
||||||
};
|
|
||||||
// update if its a off-session mit payment
|
|
||||||
if check_for_mit_mandates {
|
if check_for_mit_mandates {
|
||||||
let connector_mandate_details =
|
let connector_mandate_details =
|
||||||
update_connector_mandate_details_in_payment_method(
|
update_connector_mandate_details_in_payment_method(
|
||||||
@ -515,14 +510,10 @@ where
|
|||||||
.await
|
.await
|
||||||
.map(|details| details.into());
|
.map(|details| details.into());
|
||||||
|
|
||||||
let pm_update =
|
payment_methods::cards::update_payment_method_and_last_used(
|
||||||
storage::PaymentMethodUpdate::PaymentMethodDataUpdate {
|
db,
|
||||||
payment_method_data: pm_data_encrypted,
|
|
||||||
};
|
|
||||||
|
|
||||||
db.update_payment_method(
|
|
||||||
existing_pm,
|
existing_pm,
|
||||||
pm_update,
|
pm_data_encrypted,
|
||||||
merchant_account.storage_scheme,
|
merchant_account.storage_scheme,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
@ -532,7 +523,7 @@ where
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => {
|
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)
|
== Some(api_models::enums::PaymentMethodType::ApplePay)
|
||||||
|| payment_method_type
|
|| payment_method_type
|
||||||
== Some(api_models::enums::PaymentMethodType::GooglePay)
|
== Some(api_models::enums::PaymentMethodType::GooglePay)
|
||||||
@ -551,7 +542,7 @@ where
|
|||||||
.find(|payment_method| {
|
.find(|payment_method| {
|
||||||
payment_method.payment_method_type == payment_method_type
|
payment_method.payment_method_type == payment_method_type
|
||||||
})
|
})
|
||||||
.map(|pm| pm.payment_method_id.clone())),
|
.cloned()),
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
if error.current_context().is_db_not_found() {
|
if error.current_context().is_db_not_found() {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
@ -570,8 +561,18 @@ where
|
|||||||
Ok(None)
|
Ok(None)
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
if let Some(customer_saved_pm_id) = customer_saved_pm_id_option {
|
if let Some(customer_saved_pm) = customer_saved_pm_option {
|
||||||
resp.payment_method_id = customer_saved_pm_id;
|
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 {
|
} else {
|
||||||
let pm_metadata =
|
let pm_metadata =
|
||||||
create_payment_method_metadata(None, connector_token)?;
|
create_payment_method_metadata(None, connector_token)?;
|
||||||
|
|||||||
Reference in New Issue
Block a user