mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-10-31 10:06:32 +08:00 
			
		
		
		
	feat(connector): [Paypal] Unify error code and error message in Paypal (#2354)
Co-authored-by: Arjun Karthik <m.arjunkarthik@gmail.com>
This commit is contained in:
		| @ -9,12 +9,12 @@ use masking::{ExposeInterface, PeekInterface, Secret}; | |||||||
| use transformers as paypal; | use transformers as paypal; | ||||||
|  |  | ||||||
| use self::transformers::{auth_headers, PaypalAuthResponse, PaypalMeta, PaypalWebhookEventType}; | use self::transformers::{auth_headers, PaypalAuthResponse, PaypalMeta, PaypalWebhookEventType}; | ||||||
| use super::utils::PaymentsCompleteAuthorizeRequestData; | use super::utils::{ConnectorErrorType, PaymentsCompleteAuthorizeRequestData}; | ||||||
| use crate::{ | use crate::{ | ||||||
|     configs::settings, |     configs::settings, | ||||||
|     connector::{ |     connector::{ | ||||||
|         utils as connector_utils, |         utils as connector_utils, | ||||||
|         utils::{to_connector_meta, RefundsRequestData}, |         utils::{to_connector_meta, ConnectorErrorTypeMapping, RefundsRequestData}, | ||||||
|     }, |     }, | ||||||
|     consts, |     consts, | ||||||
|     core::{ |     core::{ | ||||||
| @ -72,7 +72,7 @@ impl Paypal { | |||||||
|         event_builder.map(|i| i.set_error_response_body(&response)); |         event_builder.map(|i| i.set_error_response_body(&response)); | ||||||
|         router_env::logger::info!(connector_response=?response); |         router_env::logger::info!(connector_response=?response); | ||||||
|  |  | ||||||
|         let error_reason = response.details.map(|order_errors| { |         let error_reason = response.details.clone().map(|order_errors| { | ||||||
|             order_errors |             order_errors | ||||||
|                 .iter() |                 .iter() | ||||||
|                 .map(|error| { |                 .map(|error| { | ||||||
| @ -92,10 +92,24 @@ impl Paypal { | |||||||
|                 }) |                 }) | ||||||
|                 .collect::<String>() |                 .collect::<String>() | ||||||
|         }); |         }); | ||||||
|  |         let errors_list = response.details.unwrap_or_default(); | ||||||
|  |         let option_error_code_message = | ||||||
|  |             connector_utils::get_error_code_error_message_based_on_priority( | ||||||
|  |                 Self.clone(), | ||||||
|  |                 errors_list | ||||||
|  |                     .into_iter() | ||||||
|  |                     .map(|errors| errors.into()) | ||||||
|  |                     .collect(), | ||||||
|  |             ); | ||||||
|         Ok(ErrorResponse { |         Ok(ErrorResponse { | ||||||
|             status_code: res.status_code, |             status_code: res.status_code, | ||||||
|             code: response.name, |             code: option_error_code_message | ||||||
|             message: response.message.clone(), |                 .clone() | ||||||
|  |                 .map(|error_code_message| error_code_message.error_code) | ||||||
|  |                 .unwrap_or(consts::NO_ERROR_CODE.to_string()), | ||||||
|  |             message: option_error_code_message | ||||||
|  |                 .map(|error_code_message| error_code_message.error_message) | ||||||
|  |                 .unwrap_or(consts::NO_ERROR_MESSAGE.to_string()), | ||||||
|             reason: error_reason.or(Some(response.message)), |             reason: error_reason.or(Some(response.message)), | ||||||
|             attempt_status: None, |             attempt_status: None, | ||||||
|             connector_transaction_id: None, |             connector_transaction_id: None, | ||||||
| @ -224,6 +238,7 @@ impl ConnectorCommon for Paypal { | |||||||
|  |  | ||||||
|         let error_reason = response |         let error_reason = response | ||||||
|             .details |             .details | ||||||
|  |             .clone() | ||||||
|             .map(|error_details| { |             .map(|error_details| { | ||||||
|                 error_details |                 error_details | ||||||
|                     .iter() |                     .iter() | ||||||
| @ -249,11 +264,25 @@ impl ConnectorCommon for Paypal { | |||||||
|                 .or(Some(err_reason)), |                 .or(Some(err_reason)), | ||||||
|             None => Some(response.message.to_owned()), |             None => Some(response.message.to_owned()), | ||||||
|         }; |         }; | ||||||
|  |         let errors_list = response.details.unwrap_or_default(); | ||||||
|  |         let option_error_code_message = | ||||||
|  |             connector_utils::get_error_code_error_message_based_on_priority( | ||||||
|  |                 Self.clone(), | ||||||
|  |                 errors_list | ||||||
|  |                     .into_iter() | ||||||
|  |                     .map(|errors| errors.into()) | ||||||
|  |                     .collect(), | ||||||
|  |             ); | ||||||
|  |  | ||||||
|         Ok(ErrorResponse { |         Ok(ErrorResponse { | ||||||
|             status_code: res.status_code, |             status_code: res.status_code, | ||||||
|             code: response.name, |             code: option_error_code_message | ||||||
|             message: response.message.clone(), |                 .clone() | ||||||
|  |                 .map(|error_code_message| error_code_message.error_code) | ||||||
|  |                 .unwrap_or(consts::NO_ERROR_CODE.to_string()), | ||||||
|  |             message: option_error_code_message | ||||||
|  |                 .map(|error_code_message| error_code_message.error_message) | ||||||
|  |                 .unwrap_or(consts::NO_ERROR_MESSAGE.to_string()), | ||||||
|             reason, |             reason, | ||||||
|             attempt_status: None, |             attempt_status: None, | ||||||
|             connector_transaction_id: None, |             connector_transaction_id: None, | ||||||
| @ -388,8 +417,8 @@ impl ConnectorIntegration<api::AccessTokenAuth, types::AccessTokenRequestData, t | |||||||
|  |  | ||||||
|         Ok(ErrorResponse { |         Ok(ErrorResponse { | ||||||
|             status_code: res.status_code, |             status_code: res.status_code, | ||||||
|             code: response.error, |             code: response.error.clone(), | ||||||
|             message: response.error_description.clone(), |             message: response.error.clone(), | ||||||
|             reason: Some(response.error_description), |             reason: Some(response.error_description), | ||||||
|             attempt_status: None, |             attempt_status: None, | ||||||
|             connector_transaction_id: None, |             connector_transaction_id: None, | ||||||
| @ -1499,3 +1528,114 @@ impl services::ConnectorRedirectResponse for Paypal { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | impl ConnectorErrorTypeMapping for Paypal { | ||||||
|  |     fn get_connector_error_type( | ||||||
|  |         &self, | ||||||
|  |         error_code: String, | ||||||
|  |         _error_message: String, | ||||||
|  |     ) -> ConnectorErrorType { | ||||||
|  |         match error_code.as_str() { | ||||||
|  |             "CANNOT_BE_NEGATIVE" => ConnectorErrorType::UserError, | ||||||
|  |             "CANNOT_BE_ZERO_OR_NEGATIVE" => ConnectorErrorType::UserError, | ||||||
|  |             "CARD_EXPIRED" => ConnectorErrorType::UserError, | ||||||
|  |             "DECIMAL_PRECISION" => ConnectorErrorType::UserError, | ||||||
|  |             "DUPLICATE_INVOICE_ID" => ConnectorErrorType::UserError, | ||||||
|  |             "INSTRUMENT_DECLINED" => ConnectorErrorType::BusinessError, | ||||||
|  |             "INTERNAL_SERVER_ERROR" => ConnectorErrorType::TechnicalError, | ||||||
|  |             "INVALID_ACCOUNT_STATUS" => ConnectorErrorType::BusinessError, | ||||||
|  |             "INVALID_CURRENCY_CODE" => ConnectorErrorType::UserError, | ||||||
|  |             "INVALID_PARAMETER_SYNTAX" => ConnectorErrorType::UserError, | ||||||
|  |             "INVALID_PARAMETER_VALUE" => ConnectorErrorType::UserError, | ||||||
|  |             "INVALID_RESOURCE_ID" => ConnectorErrorType::UserError, | ||||||
|  |             "INVALID_STRING_LENGTH" => ConnectorErrorType::UserError, | ||||||
|  |             "MISSING_REQUIRED_PARAMETER" => ConnectorErrorType::UserError, | ||||||
|  |             "PAYER_ACCOUNT_LOCKED_OR_CLOSED" => ConnectorErrorType::BusinessError, | ||||||
|  |             "PAYER_ACCOUNT_RESTRICTED" => ConnectorErrorType::BusinessError, | ||||||
|  |             "PAYER_CANNOT_PAY" => ConnectorErrorType::BusinessError, | ||||||
|  |             "PERMISSION_DENIED" => ConnectorErrorType::BusinessError, | ||||||
|  |             "INVALID_ARRAY_MAX_ITEMS" => ConnectorErrorType::UserError, | ||||||
|  |             "INVALID_ARRAY_MIN_ITEMS" => ConnectorErrorType::UserError, | ||||||
|  |             "INVALID_COUNTRY_CODE" => ConnectorErrorType::UserError, | ||||||
|  |             "NOT_SUPPORTED" => ConnectorErrorType::BusinessError, | ||||||
|  |             "PAYPAL_REQUEST_ID_REQUIRED" => ConnectorErrorType::UserError, | ||||||
|  |             "MALFORMED_REQUEST_JSON" => ConnectorErrorType::UserError, | ||||||
|  |             "PERMISSION_DENIED_FOR_DONATION_ITEMS" => ConnectorErrorType::BusinessError, | ||||||
|  |             "MALFORMED_REQUEST" => ConnectorErrorType::TechnicalError, | ||||||
|  |             "AMOUNT_MISMATCH" => ConnectorErrorType::UserError, | ||||||
|  |             "BILLING_ADDRESS_INVALID" => ConnectorErrorType::UserError, | ||||||
|  |             "CITY_REQUIRED" => ConnectorErrorType::UserError, | ||||||
|  |             "DONATION_ITEMS_NOT_SUPPORTED" => ConnectorErrorType::BusinessError, | ||||||
|  |             "DUPLICATE_REFERENCE_ID" => ConnectorErrorType::UserError, | ||||||
|  |             "INVALID_PAYER_ID" => ConnectorErrorType::UserError, | ||||||
|  |             "ITEM_TOTAL_REQUIRED" => ConnectorErrorType::UserError, | ||||||
|  |             "MAX_VALUE_EXCEEDED" => ConnectorErrorType::UserError, | ||||||
|  |             "MISSING_PICKUP_ADDRESS" => ConnectorErrorType::UserError, | ||||||
|  |             "MULTI_CURRENCY_ORDER" => ConnectorErrorType::BusinessError, | ||||||
|  |             "MULTIPLE_ITEM_CATEGORIES" => ConnectorErrorType::UserError, | ||||||
|  |             "MULTIPLE_SHIPPING_ADDRESS_NOT_SUPPORTED" => ConnectorErrorType::UserError, | ||||||
|  |             "MULTIPLE_SHIPPING_TYPE_NOT_SUPPORTED" => ConnectorErrorType::BusinessError, | ||||||
|  |             "PAYEE_ACCOUNT_INVALID" => ConnectorErrorType::UserError, | ||||||
|  |             "PAYEE_ACCOUNT_LOCKED_OR_CLOSED" => ConnectorErrorType::UserError, | ||||||
|  |             "REFERENCE_ID_REQUIRED" => ConnectorErrorType::UserError, | ||||||
|  |             "PAYMENT_SOURCE_CANNOT_BE_USED" => ConnectorErrorType::BusinessError, | ||||||
|  |             "PAYMENT_SOURCE_DECLINED_BY_PROCESSOR" => ConnectorErrorType::BusinessError, | ||||||
|  |             "PAYMENT_SOURCE_INFO_CANNOT_BE_VERIFIED" => ConnectorErrorType::BusinessError, | ||||||
|  |             "POSTAL_CODE_REQUIRED" => ConnectorErrorType::UserError, | ||||||
|  |             "SHIPPING_ADDRESS_INVALID" => ConnectorErrorType::UserError, | ||||||
|  |             "TAX_TOTAL_MISMATCH" => ConnectorErrorType::UserError, | ||||||
|  |             "TAX_TOTAL_REQUIRED" => ConnectorErrorType::UserError, | ||||||
|  |             "UNSUPPORTED_INTENT" => ConnectorErrorType::BusinessError, | ||||||
|  |             "UNSUPPORTED_PAYMENT_INSTRUCTION" => ConnectorErrorType::UserError, | ||||||
|  |             "SHIPPING_TYPE_NOT_SUPPORTED_FOR_CLIENT" => ConnectorErrorType::BusinessError, | ||||||
|  |             "UNSUPPORTED_SHIPPING_TYPE" => ConnectorErrorType::BusinessError, | ||||||
|  |             "PREFERRED_SHIPPING_OPTION_AMOUNT_MISMATCH" => ConnectorErrorType::UserError, | ||||||
|  |             "CARD_CLOSED" => ConnectorErrorType::BusinessError, | ||||||
|  |             "ORDER_CANNOT_BE_SAVED" => ConnectorErrorType::BusinessError, | ||||||
|  |             "SAVE_ORDER_NOT_SUPPORTED" => ConnectorErrorType::BusinessError, | ||||||
|  |             "FIELD_NOT_PATCHABLE" => ConnectorErrorType::UserError, | ||||||
|  |             "AMOUNT_NOT_PATCHABLE" => ConnectorErrorType::UserError, | ||||||
|  |             "INVALID_PATCH_OPERATION" => ConnectorErrorType::UserError, | ||||||
|  |             "PAYEE_ACCOUNT_NOT_SUPPORTED" => ConnectorErrorType::UserError, | ||||||
|  |             "PAYEE_ACCOUNT_NOT_VERIFIED" => ConnectorErrorType::UserError, | ||||||
|  |             "PAYEE_NOT_CONSENTED" => ConnectorErrorType::UserError, | ||||||
|  |             "INVALID_JSON_POINTER_FORMAT" => ConnectorErrorType::BusinessError, | ||||||
|  |             "INVALID_PARAMETER" => ConnectorErrorType::UserError, | ||||||
|  |             "NOT_PATCHABLE" => ConnectorErrorType::BusinessError, | ||||||
|  |             "PATCH_VALUE_REQUIRED" => ConnectorErrorType::UserError, | ||||||
|  |             "PATCH_PATH_REQUIRED" => ConnectorErrorType::UserError, | ||||||
|  |             "REFERENCE_ID_NOT_FOUND" => ConnectorErrorType::UserError, | ||||||
|  |             "SHIPPING_OPTION_NOT_SELECTED" => ConnectorErrorType::UserError, | ||||||
|  |             "SHIPPING_OPTIONS_NOT_SUPPORTED" => ConnectorErrorType::BusinessError, | ||||||
|  |             "MULTIPLE_SHIPPING_OPTION_SELECTED" => ConnectorErrorType::UserError, | ||||||
|  |             "ORDER_ALREADY_COMPLETED" => ConnectorErrorType::BusinessError, | ||||||
|  |             "ACTION_DOES_NOT_MATCH_INTENT" => ConnectorErrorType::BusinessError, | ||||||
|  |             "AGREEMENT_ALREADY_CANCELLED" => ConnectorErrorType::BusinessError, | ||||||
|  |             "BILLING_AGREEMENT_NOT_FOUND" => ConnectorErrorType::BusinessError, | ||||||
|  |             "DOMESTIC_TRANSACTION_REQUIRED" => ConnectorErrorType::BusinessError, | ||||||
|  |             "ORDER_NOT_APPROVED" => ConnectorErrorType::UserError, | ||||||
|  |             "MAX_NUMBER_OF_PAYMENT_ATTEMPTS_EXCEEDED" => ConnectorErrorType::TechnicalError, | ||||||
|  |             "PAYEE_BLOCKED_TRANSACTION" => ConnectorErrorType::BusinessError, | ||||||
|  |             "TRANSACTION_LIMIT_EXCEEDED" => ConnectorErrorType::UserError, | ||||||
|  |             "TRANSACTION_RECEIVING_LIMIT_EXCEEDED" => ConnectorErrorType::BusinessError, | ||||||
|  |             "TRANSACTION_REFUSED" => ConnectorErrorType::TechnicalError, | ||||||
|  |             "ORDER_ALREADY_AUTHORIZED" => ConnectorErrorType::BusinessError, | ||||||
|  |             "AUTH_CAPTURE_NOT_ENABLED" => ConnectorErrorType::BusinessError, | ||||||
|  |             "AMOUNT_CANNOT_BE_SPECIFIED" => ConnectorErrorType::BusinessError, | ||||||
|  |             "AUTHORIZATION_AMOUNT_EXCEEDED" => ConnectorErrorType::UserError, | ||||||
|  |             "AUTHORIZATION_CURRENCY_MISMATCH" => ConnectorErrorType::UserError, | ||||||
|  |             "MAX_AUTHORIZATION_COUNT_EXCEEDED" => ConnectorErrorType::BusinessError, | ||||||
|  |             "ORDER_COMPLETED_OR_VOIDED" => ConnectorErrorType::BusinessError, | ||||||
|  |             "ORDER_EXPIRED" => ConnectorErrorType::BusinessError, | ||||||
|  |             "INVALID_PICKUP_ADDRESS" => ConnectorErrorType::UserError, | ||||||
|  |             "CONSENT_NEEDED" => ConnectorErrorType::UserError, | ||||||
|  |             "COMPLIANCE_VIOLATION" => ConnectorErrorType::BusinessError, | ||||||
|  |             "REDIRECT_PAYER_FOR_ALTERNATE_FUNDING" => ConnectorErrorType::TechnicalError, | ||||||
|  |             "ORDER_ALREADY_CAPTURED" => ConnectorErrorType::UserError, | ||||||
|  |             "TRANSACTION_BLOCKED_BY_PAYEE" => ConnectorErrorType::BusinessError, | ||||||
|  |             "NOT_ENABLED_FOR_CARD_PROCESSING" => ConnectorErrorType::BusinessError, | ||||||
|  |             "PAYEE_NOT_ENABLED_FOR_CARD_PROCESSING" => ConnectorErrorType::BusinessError, | ||||||
|  |             _ => ConnectorErrorType::UnknownError, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | |||||||
| @ -2173,3 +2173,21 @@ fn get_headers( | |||||||
|         .to_owned(); |         .to_owned(); | ||||||
|     Ok(header_value) |     Ok(header_value) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | impl From<OrderErrorDetails> for utils::ErrorCodeAndMessage { | ||||||
|  |     fn from(error: OrderErrorDetails) -> Self { | ||||||
|  |         Self { | ||||||
|  |             error_code: error.issue.to_string(), | ||||||
|  |             error_message: error.issue.to_string(), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl From<ErrorDetails> for utils::ErrorCodeAndMessage { | ||||||
|  |     fn from(error: ErrorDetails) -> Self { | ||||||
|  |         Self { | ||||||
|  |             error_code: error.issue.to_string(), | ||||||
|  |             error_message: error.issue.to_string(), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Swangi Kumari
					Swangi Kumari