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:
Swangi Kumari
2024-03-15 17:57:46 +05:30
committed by GitHub
parent 290c456a23
commit fc81f90f61
2 changed files with 167 additions and 9 deletions

View File

@ -9,12 +9,12 @@ use masking::{ExposeInterface, PeekInterface, Secret};
use transformers as paypal;
use self::transformers::{auth_headers, PaypalAuthResponse, PaypalMeta, PaypalWebhookEventType};
use super::utils::PaymentsCompleteAuthorizeRequestData;
use super::utils::{ConnectorErrorType, PaymentsCompleteAuthorizeRequestData};
use crate::{
configs::settings,
connector::{
utils as connector_utils,
utils::{to_connector_meta, RefundsRequestData},
utils::{to_connector_meta, ConnectorErrorTypeMapping, RefundsRequestData},
},
consts,
core::{
@ -72,7 +72,7 @@ impl Paypal {
event_builder.map(|i| i.set_error_response_body(&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
.iter()
.map(|error| {
@ -92,10 +92,24 @@ impl Paypal {
})
.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 {
status_code: res.status_code,
code: response.name,
message: response.message.clone(),
code: option_error_code_message
.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)),
attempt_status: None,
connector_transaction_id: None,
@ -224,6 +238,7 @@ impl ConnectorCommon for Paypal {
let error_reason = response
.details
.clone()
.map(|error_details| {
error_details
.iter()
@ -249,11 +264,25 @@ impl ConnectorCommon for Paypal {
.or(Some(err_reason)),
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 {
status_code: res.status_code,
code: response.name,
message: response.message.clone(),
code: option_error_code_message
.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,
attempt_status: None,
connector_transaction_id: None,
@ -388,8 +417,8 @@ impl ConnectorIntegration<api::AccessTokenAuth, types::AccessTokenRequestData, t
Ok(ErrorResponse {
status_code: res.status_code,
code: response.error,
message: response.error_description.clone(),
code: response.error.clone(),
message: response.error.clone(),
reason: Some(response.error_description),
attempt_status: 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,
}
}
}

View File

@ -2173,3 +2173,21 @@ fn get_headers(
.to_owned();
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(),
}
}
}