mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-30 17:47:54 +08:00
refactor(payment_methods): prevent deletion of default payment method for a customer (#3964)
This commit is contained in:
@ -251,6 +251,8 @@ pub enum StripeErrorCode {
|
|||||||
InvalidConnectorConfiguration { config: String },
|
InvalidConnectorConfiguration { config: String },
|
||||||
#[error(error_type = StripeErrorType::HyperswitchError, code = "HE_01", message = "Failed to convert currency to minor unit")]
|
#[error(error_type = StripeErrorType::HyperswitchError, code = "HE_01", message = "Failed to convert currency to minor unit")]
|
||||||
CurrencyConversionFailed,
|
CurrencyConversionFailed,
|
||||||
|
#[error(error_type = StripeErrorType::InvalidRequestError, code = "IR_25", message = "Cannot delete the default payment method")]
|
||||||
|
PaymentMethodDeleteFailed,
|
||||||
// [#216]: https://github.com/juspay/hyperswitch/issues/216
|
// [#216]: https://github.com/juspay/hyperswitch/issues/216
|
||||||
// Implement the remaining stripe error codes
|
// Implement the remaining stripe error codes
|
||||||
|
|
||||||
@ -618,6 +620,7 @@ impl From<errors::ApiErrorResponse> for StripeErrorCode {
|
|||||||
Self::InvalidConnectorConfiguration { config }
|
Self::InvalidConnectorConfiguration { config }
|
||||||
}
|
}
|
||||||
errors::ApiErrorResponse::CurrencyConversionFailed => Self::CurrencyConversionFailed,
|
errors::ApiErrorResponse::CurrencyConversionFailed => Self::CurrencyConversionFailed,
|
||||||
|
errors::ApiErrorResponse::PaymentMethodDeleteFailed => Self::PaymentMethodDeleteFailed,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -686,7 +689,8 @@ impl actix_web::ResponseError for StripeErrorCode {
|
|||||||
| Self::DuplicateCustomer
|
| Self::DuplicateCustomer
|
||||||
| Self::PaymentMethodUnactivated
|
| Self::PaymentMethodUnactivated
|
||||||
| Self::InvalidConnectorConfiguration { .. }
|
| Self::InvalidConnectorConfiguration { .. }
|
||||||
| Self::CurrencyConversionFailed => StatusCode::BAD_REQUEST,
|
| Self::CurrencyConversionFailed
|
||||||
|
| Self::PaymentMethodDeleteFailed => StatusCode::BAD_REQUEST,
|
||||||
Self::RefundFailed
|
Self::RefundFailed
|
||||||
| Self::PayoutFailed
|
| Self::PayoutFailed
|
||||||
| Self::PaymentLinkNotFound
|
| Self::PaymentLinkNotFound
|
||||||
|
|||||||
@ -252,6 +252,8 @@ pub enum ApiErrorResponse {
|
|||||||
InvalidConnectorConfiguration { config: String },
|
InvalidConnectorConfiguration { config: String },
|
||||||
#[error(error_type = ErrorType::ValidationError, code = "HE_01", message = "Failed to convert currency to minor unit")]
|
#[error(error_type = ErrorType::ValidationError, code = "HE_01", message = "Failed to convert currency to minor unit")]
|
||||||
CurrencyConversionFailed,
|
CurrencyConversionFailed,
|
||||||
|
#[error(error_type = ErrorType::InvalidRequestError, code = "IR_25", message = "Cannot delete the default payment method")]
|
||||||
|
PaymentMethodDeleteFailed,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PTError for ApiErrorResponse {
|
impl PTError for ApiErrorResponse {
|
||||||
|
|||||||
@ -281,6 +281,9 @@ impl ErrorSwitch<api_models::errors::types::ApiErrorResponse> for ApiErrorRespon
|
|||||||
Self::CurrencyConversionFailed => {
|
Self::CurrencyConversionFailed => {
|
||||||
AER::Unprocessable(ApiError::new("HE", 2, "Failed to convert currency to minor unit", None))
|
AER::Unprocessable(ApiError::new("HE", 2, "Failed to convert currency to minor unit", None))
|
||||||
}
|
}
|
||||||
|
Self::PaymentMethodDeleteFailed => {
|
||||||
|
AER::BadRequest(ApiError::new("IR", 25, "Cannot delete the default payment method", None))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3428,6 +3428,7 @@ pub async fn delete_payment_method(
|
|||||||
state: routes::AppState,
|
state: routes::AppState,
|
||||||
merchant_account: domain::MerchantAccount,
|
merchant_account: domain::MerchantAccount,
|
||||||
pm_id: api::PaymentMethodId,
|
pm_id: api::PaymentMethodId,
|
||||||
|
key_store: domain::MerchantKeyStore,
|
||||||
) -> errors::RouterResponse<api::PaymentMethodDeleteResponse> {
|
) -> errors::RouterResponse<api::PaymentMethodDeleteResponse> {
|
||||||
let db = state.store.as_ref();
|
let db = state.store.as_ref();
|
||||||
let key = db
|
let key = db
|
||||||
@ -3435,6 +3436,21 @@ pub async fn delete_payment_method(
|
|||||||
.await
|
.await
|
||||||
.to_not_found_response(errors::ApiErrorResponse::PaymentMethodNotFound)?;
|
.to_not_found_response(errors::ApiErrorResponse::PaymentMethodNotFound)?;
|
||||||
|
|
||||||
|
let customer = db
|
||||||
|
.find_customer_by_customer_id_merchant_id(
|
||||||
|
&key.customer_id,
|
||||||
|
&merchant_account.merchant_id,
|
||||||
|
&key_store,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.to_not_found_response(errors::ApiErrorResponse::InternalServerError)
|
||||||
|
.attach_printable("Customer not found for the payment method")?;
|
||||||
|
|
||||||
|
utils::when(
|
||||||
|
customer.default_payment_method_id.as_ref() == Some(&pm_id.payment_method_id),
|
||||||
|
|| Err(errors::ApiErrorResponse::PaymentMethodDeleteFailed),
|
||||||
|
)?;
|
||||||
|
|
||||||
if key.payment_method == enums::PaymentMethod::Card {
|
if key.payment_method == enums::PaymentMethod::Card {
|
||||||
let response = delete_card_from_locker(
|
let response = delete_card_from_locker(
|
||||||
&state,
|
&state,
|
||||||
|
|||||||
@ -253,7 +253,9 @@ pub async fn payment_method_delete_api(
|
|||||||
state,
|
state,
|
||||||
&req,
|
&req,
|
||||||
pm,
|
pm,
|
||||||
|state, auth, req| cards::delete_payment_method(state, auth.merchant_account, req),
|
|state, auth, req| {
|
||||||
|
cards::delete_payment_method(state, auth.merchant_account, req, auth.key_store)
|
||||||
|
},
|
||||||
&auth::ApiKeyAuth,
|
&auth::ApiKeyAuth,
|
||||||
api_locking::LockAction::NotApplicable,
|
api_locking::LockAction::NotApplicable,
|
||||||
))
|
))
|
||||||
|
|||||||
Reference in New Issue
Block a user