mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-10-31 10:06:32 +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
	 Chethan Rao
					Chethan Rao