mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-02 12:06:56 +08:00
fix(connector): [Bluesnap] fix psync status to failure when it is '403' (#2772)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
@ -37,6 +37,8 @@ use crate::{
|
|||||||
utils::{self, BytesExt},
|
utils::{self, BytesExt},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const BLUESNAP_TRANSACTION_NOT_FOUND: &str = "is not authorized to view merchant-transaction:";
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Bluesnap;
|
pub struct Bluesnap;
|
||||||
|
|
||||||
@ -132,12 +134,24 @@ impl ConnectorCommon for Bluesnap {
|
|||||||
message: error_res.error_name.clone().unwrap_or(error_res.error_code),
|
message: error_res.error_name.clone().unwrap_or(error_res.error_code),
|
||||||
reason: Some(error_res.error_description),
|
reason: Some(error_res.error_description),
|
||||||
},
|
},
|
||||||
bluesnap::BluesnapErrors::General(error_response) => ErrorResponse {
|
bluesnap::BluesnapErrors::General(error_response) => {
|
||||||
status_code: res.status_code,
|
let error_res = if res.status_code == 403
|
||||||
code: consts::NO_ERROR_CODE.to_string(),
|
&& error_response.contains(BLUESNAP_TRANSACTION_NOT_FOUND)
|
||||||
message: error_response.clone(),
|
{
|
||||||
reason: Some(error_response),
|
format!(
|
||||||
},
|
"{} in bluesnap dashboard",
|
||||||
|
consts::REQUEST_TIMEOUT_PAYMENT_NOT_FOUND
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
error_response.clone()
|
||||||
|
};
|
||||||
|
ErrorResponse {
|
||||||
|
status_code: res.status_code,
|
||||||
|
code: consts::NO_ERROR_CODE.to_string(),
|
||||||
|
message: error_response,
|
||||||
|
reason: Some(error_res),
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
Ok(response_error_message)
|
Ok(response_error_message)
|
||||||
}
|
}
|
||||||
@ -322,21 +336,26 @@ impl ConnectorIntegration<api::PSync, types::PaymentsSyncData, types::PaymentsRe
|
|||||||
req: &types::PaymentsSyncRouterData,
|
req: &types::PaymentsSyncRouterData,
|
||||||
connectors: &settings::Connectors,
|
connectors: &settings::Connectors,
|
||||||
) -> CustomResult<String, errors::ConnectorError> {
|
) -> CustomResult<String, errors::ConnectorError> {
|
||||||
let meta_data: CustomResult<bluesnap::BluesnapConnectorMetaData, errors::ConnectorError> =
|
let connector_transaction_id = req.request.connector_transaction_id.clone();
|
||||||
connector_utils::to_connector_meta_from_secret(req.connector_meta_data.clone());
|
match connector_transaction_id {
|
||||||
|
// if connector_transaction_id is present, we always sync with connector_transaction_id
|
||||||
match meta_data {
|
types::ResponseId::ConnectorTransactionId(trans_id) => {
|
||||||
// if merchant_id is present, psync can be made using merchant_transaction_id
|
get_psync_url_with_connector_transaction_id(
|
||||||
Ok(data) => get_url_with_merchant_transaction_id(
|
trans_id,
|
||||||
self.base_url(connectors).to_string(),
|
self.base_url(connectors).to_string(),
|
||||||
data.merchant_id,
|
)
|
||||||
req.attempt_id.to_owned(),
|
}
|
||||||
),
|
_ => {
|
||||||
// otherwise psync is made using connector_transaction_id
|
// if connector_transaction_id is not present, we sync with merchant_transaction_id
|
||||||
Err(_) => get_psync_url_with_connector_transaction_id(
|
let meta_data: bluesnap::BluesnapConnectorMetaData =
|
||||||
&req.request.connector_transaction_id,
|
connector_utils::to_connector_meta_from_secret(req.connector_meta_data.clone())
|
||||||
self.base_url(connectors).to_string(),
|
.change_context(errors::ConnectorError::ResponseHandlingFailed)?;
|
||||||
),
|
get_url_with_merchant_transaction_id(
|
||||||
|
self.base_url(connectors).to_string(),
|
||||||
|
meta_data.merchant_id,
|
||||||
|
req.attempt_id.to_owned(),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1269,12 +1288,9 @@ fn get_url_with_merchant_transaction_id(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_psync_url_with_connector_transaction_id(
|
fn get_psync_url_with_connector_transaction_id(
|
||||||
connector_transaction_id: &types::ResponseId,
|
connector_transaction_id: String,
|
||||||
base_url: String,
|
base_url: String,
|
||||||
) -> CustomResult<String, errors::ConnectorError> {
|
) -> CustomResult<String, errors::ConnectorError> {
|
||||||
let connector_transaction_id = connector_transaction_id
|
|
||||||
.get_connector_transaction_id()
|
|
||||||
.change_context(errors::ConnectorError::MissingConnectorTransactionID)?;
|
|
||||||
Ok(format!(
|
Ok(format!(
|
||||||
"{}{}{}",
|
"{}{}{}",
|
||||||
base_url, "services/2/transactions/", connector_transaction_id
|
base_url, "services/2/transactions/", connector_transaction_id
|
||||||
|
|||||||
@ -13,6 +13,7 @@ pub(crate) const ALPHABETS: [char; 62] = [
|
|||||||
pub const REQUEST_TIME_OUT: u64 = 30;
|
pub const REQUEST_TIME_OUT: u64 = 30;
|
||||||
pub const REQUEST_TIMEOUT_ERROR_CODE: &str = "TIMEOUT";
|
pub const REQUEST_TIMEOUT_ERROR_CODE: &str = "TIMEOUT";
|
||||||
pub const REQUEST_TIMEOUT_ERROR_MESSAGE: &str = "Connector did not respond in specified time";
|
pub const REQUEST_TIMEOUT_ERROR_MESSAGE: &str = "Connector did not respond in specified time";
|
||||||
|
pub const REQUEST_TIMEOUT_PAYMENT_NOT_FOUND: &str = "Timed out ,payment not found";
|
||||||
pub const REQUEST_TIMEOUT_ERROR_MESSAGE_FROM_PSYNC: &str =
|
pub const REQUEST_TIMEOUT_ERROR_MESSAGE_FROM_PSYNC: &str =
|
||||||
"This Payment has been moved to failed as there is no response from the connector";
|
"This Payment has been moved to failed as there is no response from the connector";
|
||||||
|
|
||||||
|
|||||||
@ -326,7 +326,7 @@ async fn payment_response_update_tracker<F: Clone, T: types::Capturable>(
|
|||||||
match err.status_code {
|
match err.status_code {
|
||||||
// marking failure for 2xx because this is genuine payment failure
|
// marking failure for 2xx because this is genuine payment failure
|
||||||
200..=299 => storage::enums::AttemptStatus::Failure,
|
200..=299 => storage::enums::AttemptStatus::Failure,
|
||||||
_ => payment_data.payment_attempt.status,
|
_ => router_data.status,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match err.status_code {
|
match err.status_code {
|
||||||
|
|||||||
@ -10,7 +10,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use actix_web::{body, web, FromRequest, HttpRequest, HttpResponse, Responder, ResponseError};
|
use actix_web::{body, web, FromRequest, HttpRequest, HttpResponse, Responder, ResponseError};
|
||||||
use api_models::enums::CaptureMethod;
|
use api_models::enums::{AttemptStatus, CaptureMethod};
|
||||||
pub use client::{proxy_bypass_urls, ApiClient, MockApiClient, ProxyClient};
|
pub use client::{proxy_bypass_urls, ApiClient, MockApiClient, ProxyClient};
|
||||||
pub use common_utils::request::{ContentType, Method, Request, RequestBuilder};
|
pub use common_utils::request::{ContentType, Method, Request, RequestBuilder};
|
||||||
use common_utils::{
|
use common_utils::{
|
||||||
@ -403,7 +403,21 @@ where
|
|||||||
500..=511 => {
|
500..=511 => {
|
||||||
connector_integration.get_5xx_error_response(body)?
|
connector_integration.get_5xx_error_response(body)?
|
||||||
}
|
}
|
||||||
_ => connector_integration.get_error_response(body)?,
|
_ => {
|
||||||
|
let error_res =
|
||||||
|
connector_integration.get_error_response(body)?;
|
||||||
|
if router_data.connector == "bluesnap"
|
||||||
|
&& error_res.status_code == 403
|
||||||
|
&& error_res.reason
|
||||||
|
== Some(format!(
|
||||||
|
"{} in bluesnap dashboard",
|
||||||
|
consts::REQUEST_TIMEOUT_PAYMENT_NOT_FOUND
|
||||||
|
))
|
||||||
|
{
|
||||||
|
router_data.status = AttemptStatus::Failure;
|
||||||
|
};
|
||||||
|
error_res
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
router_data.response = Err(error);
|
router_data.response = Err(error);
|
||||||
|
|||||||
Reference in New Issue
Block a user