mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 09:07:09 +08:00
refactor(payment_methods): allow deletion of default payment method for a customer if only one pm exists (#4027)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
@ -3201,7 +3201,7 @@ pub async fn set_default_payment_method(
|
||||
)?;
|
||||
|
||||
let customer_update = CustomerUpdate::UpdateDefaultPaymentMethod {
|
||||
default_payment_method_id: Some(payment_method_id.to_owned()),
|
||||
default_payment_method_id: Some(Some(payment_method_id.to_owned())),
|
||||
};
|
||||
|
||||
// update the db with the default payment method id
|
||||
@ -3450,6 +3450,16 @@ pub async fn delete_payment_method(
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::PaymentMethodNotFound)?;
|
||||
|
||||
let payment_methods_count = db
|
||||
.get_payment_method_count_by_customer_id_merchant_id_status(
|
||||
&key.customer_id,
|
||||
&merchant_account.merchant_id,
|
||||
api_enums::PaymentMethodStatus::Active,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed to get a count of payment methods for a customer")?;
|
||||
|
||||
let customer = db
|
||||
.find_customer_by_customer_id_merchant_id(
|
||||
&key.customer_id,
|
||||
@ -3461,7 +3471,8 @@ pub async fn delete_payment_method(
|
||||
.attach_printable("Customer not found for the payment method")?;
|
||||
|
||||
utils::when(
|
||||
customer.default_payment_method_id.as_ref() == Some(&pm_id.payment_method_id),
|
||||
customer.default_payment_method_id.as_ref() == Some(&pm_id.payment_method_id)
|
||||
&& payment_methods_count > 1,
|
||||
|| Err(errors::ApiErrorResponse::PaymentMethodDeleteFailed),
|
||||
)?;
|
||||
|
||||
@ -3489,6 +3500,22 @@ pub async fn delete_payment_method(
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::PaymentMethodNotFound)?;
|
||||
|
||||
if customer.default_payment_method_id.as_ref() == Some(&pm_id.payment_method_id) {
|
||||
let customer_update = CustomerUpdate::UpdateDefaultPaymentMethod {
|
||||
default_payment_method_id: Some(None),
|
||||
};
|
||||
|
||||
db.update_customer_by_customer_id_merchant_id(
|
||||
key.customer_id,
|
||||
key.merchant_id,
|
||||
customer_update,
|
||||
&key_store,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed to update the default payment method id for the customer")?;
|
||||
};
|
||||
|
||||
Ok(services::ApplicationResponse::Json(
|
||||
api::PaymentMethodDeleteResponse {
|
||||
payment_method_id: key.payment_method_id,
|
||||
|
||||
@ -1299,6 +1299,21 @@ impl PaymentMethodInterface for KafkaStore {
|
||||
.await
|
||||
}
|
||||
|
||||
async fn get_payment_method_count_by_customer_id_merchant_id_status(
|
||||
&self,
|
||||
customer_id: &str,
|
||||
merchant_id: &str,
|
||||
status: common_enums::PaymentMethodStatus,
|
||||
) -> CustomResult<i64, errors::StorageError> {
|
||||
self.diesel_store
|
||||
.get_payment_method_count_by_customer_id_merchant_id_status(
|
||||
customer_id,
|
||||
merchant_id,
|
||||
status,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn find_payment_method_by_locker_id(
|
||||
&self,
|
||||
locker_id: &str,
|
||||
|
||||
@ -36,6 +36,13 @@ pub trait PaymentMethodInterface {
|
||||
limit: Option<i64>,
|
||||
) -> CustomResult<Vec<storage::PaymentMethod>, errors::StorageError>;
|
||||
|
||||
async fn get_payment_method_count_by_customer_id_merchant_id_status(
|
||||
&self,
|
||||
customer_id: &str,
|
||||
merchant_id: &str,
|
||||
status: common_enums::PaymentMethodStatus,
|
||||
) -> CustomResult<i64, errors::StorageError>;
|
||||
|
||||
async fn insert_payment_method(
|
||||
&self,
|
||||
payment_method_new: storage::PaymentMethodNew,
|
||||
@ -80,6 +87,25 @@ impl PaymentMethodInterface for Store {
|
||||
.into_report()
|
||||
}
|
||||
|
||||
#[instrument(skip_all)]
|
||||
async fn get_payment_method_count_by_customer_id_merchant_id_status(
|
||||
&self,
|
||||
customer_id: &str,
|
||||
merchant_id: &str,
|
||||
status: common_enums::PaymentMethodStatus,
|
||||
) -> CustomResult<i64, errors::StorageError> {
|
||||
let conn = connection::pg_connection_read(self).await?;
|
||||
storage::PaymentMethod::get_count_by_customer_id_merchant_id_status(
|
||||
&conn,
|
||||
customer_id,
|
||||
merchant_id,
|
||||
status,
|
||||
)
|
||||
.await
|
||||
.map_err(Into::into)
|
||||
.into_report()
|
||||
}
|
||||
|
||||
#[instrument(skip_all)]
|
||||
async fn insert_payment_method(
|
||||
&self,
|
||||
@ -204,6 +230,27 @@ impl PaymentMethodInterface for MockDb {
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_payment_method_count_by_customer_id_merchant_id_status(
|
||||
&self,
|
||||
customer_id: &str,
|
||||
merchant_id: &str,
|
||||
status: common_enums::PaymentMethodStatus,
|
||||
) -> CustomResult<i64, errors::StorageError> {
|
||||
let payment_methods = self.payment_methods.lock().await;
|
||||
let count = payment_methods
|
||||
.iter()
|
||||
.filter(|pm| {
|
||||
pm.customer_id == customer_id
|
||||
&& pm.merchant_id == merchant_id
|
||||
&& pm.status == status
|
||||
})
|
||||
.count();
|
||||
count
|
||||
.try_into()
|
||||
.into_report()
|
||||
.change_context(errors::StorageError::MockDbError)
|
||||
}
|
||||
|
||||
async fn insert_payment_method(
|
||||
&self,
|
||||
payment_method_new: storage::PaymentMethodNew,
|
||||
|
||||
@ -118,7 +118,7 @@ pub enum CustomerUpdate {
|
||||
connector_customer: Option<serde_json::Value>,
|
||||
},
|
||||
UpdateDefaultPaymentMethod {
|
||||
default_payment_method_id: Option<String>,
|
||||
default_payment_method_id: Option<Option<String>>,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user