Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: noon payme cryptopay error mapping #3656

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions crates/router/src/connector/bankofamerica/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1446,9 +1446,9 @@ impl<F>
resource_id: types::ResponseId::NoResponseId,
redirection_data,
mandate_reference: None,
connector_metadata: Some(
serde_json::json!({"three_ds_data":three_ds_data}),
),
connector_metadata: Some(serde_json::json!({
"three_ds_data": three_ds_data
})),
network_txn_id: None,
connector_response_reference_id,
incremental_authorization_allowed: None,
Expand Down
41 changes: 31 additions & 10 deletions crates/router/src/connector/cryptopay/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use reqwest::Url;
use serde::{Deserialize, Serialize};

use crate::{
connector::utils::{self, CryptoData},
connector::utils::{self, is_payment_failure, CryptoData},
consts,
core::errors,
services,
types::{self, api, storage::enums},
Expand Down Expand Up @@ -155,14 +156,30 @@ impl<F, T>
types::PaymentsResponseData,
>,
) -> Result<Self, Self::Error> {
let redirection_data = item
.response
.data
.hosted_page_url
.map(|x| services::RedirectForm::from((x, services::Method::Get)));
Ok(Self {
status: enums::AttemptStatus::from(item.response.data.status),
response: Ok(types::PaymentsResponseData::TransactionResponse {
let status = enums::AttemptStatus::from(item.response.data.status.clone());
let response = if is_payment_failure(status) {
let payment_response = &item.response.data;
Err(types::ErrorResponse {
code: payment_response
.name
.clone()
.unwrap_or(consts::NO_ERROR_CODE.to_string()),
message: payment_response
.status_context
.clone()
.unwrap_or(consts::NO_ERROR_MESSAGE.to_string()),
reason: payment_response.status_context.clone(),
status_code: item.http_code,
attempt_status: None,
connector_transaction_id: Some(payment_response.id.clone()),
})
} else {
let redirection_data = item
.response
.data
.hosted_page_url
.map(|x| services::RedirectForm::from((x, services::Method::Get)));
Ok(types::PaymentsResponseData::TransactionResponse {
resource_id: types::ResponseId::ConnectorTransactionId(
item.response.data.id.clone(),
),
Expand All @@ -176,7 +193,11 @@ impl<F, T>
.custom_id
.or(Some(item.response.data.id)),
incremental_authorization_allowed: None,
}),
})
};
Ok(Self {
status,
response,
..item.data
})
}
Expand Down
69 changes: 54 additions & 15 deletions crates/router/src/connector/noon/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use serde::{Deserialize, Serialize};

use crate::{
connector::utils::{
self as conn_utils, CardData, PaymentsAuthorizeRequestData, RevokeMandateRequestData,
RouterData, WalletData,
self as conn_utils, is_refund_failure, CardData, PaymentsAuthorizeRequestData,
RevokeMandateRequestData, RouterData, WalletData,
},
core::{errors, mandate::MandateBehaviour},
services,
Expand Down Expand Up @@ -555,6 +555,8 @@ impl<F, T>
fn try_from(
item: types::ResponseRouterData<F, NoonPaymentsResponse, T, types::PaymentsResponseData>,
) -> Result<Self, Self::Error> {
let order = item.response.result.order;
let status = enums::AttemptStatus::foreign_from((order.status, item.data.status));
let redirection_data = item.response.result.checkout_data.map(|redirection_data| {
services::RedirectForm::Form {
endpoint: redirection_data.post_url.to_string(),
Expand All @@ -570,17 +572,16 @@ impl<F, T>
connector_mandate_id: Some(subscription_data.identifier),
payment_method_id: None,
});
let order = item.response.result.order;
Ok(Self {
status: enums::AttemptStatus::foreign_from((order.status, item.data.status)),
status,
response: match order.error_message {
Some(error_message) => Err(ErrorResponse {
code: order.error_code.to_string(),
message: error_message.clone(),
reason: Some(error_message),
status_code: item.http_code,
attempt_status: None,
connector_transaction_id: None,
attempt_status: Some(status),
connector_transaction_id: Some(order.id.to_string()),
}),
_ => {
let connector_response_reference_id =
Expand Down Expand Up @@ -784,13 +785,18 @@ pub struct NoonPaymentsTransactionResponse {
}

#[derive(Default, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct NoonRefundResponseResult {
transaction: NoonPaymentsTransactionResponse,
}

#[derive(Default, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RefundResponse {
result: NoonRefundResponseResult,
result_code: u32,
class_description: String,
message: String,
}

impl TryFrom<types::RefundsResponseRouterData<api::Execute, RefundResponse>>
Expand All @@ -800,11 +806,26 @@ impl TryFrom<types::RefundsResponseRouterData<api::Execute, RefundResponse>>
fn try_from(
item: types::RefundsResponseRouterData<api::Execute, RefundResponse>,
) -> Result<Self, Self::Error> {
Ok(Self {
response: Ok(types::RefundsResponseData {
let response = &item.response;
let refund_status =
enums::RefundStatus::from(response.result.transaction.status.to_owned());
let response = if is_refund_failure(refund_status) {
Err(ErrorResponse {
status_code: item.http_code,
code: response.result_code.to_string(),
message: response.class_description.clone(),
reason: Some(response.message.clone()),
attempt_status: None,
connector_transaction_id: Some(response.result.transaction.id.clone()),
})
} else {
Ok(types::RefundsResponseData {
connector_refund_id: item.response.result.transaction.id,
refund_status: enums::RefundStatus::from(item.response.result.transaction.status),
}),
refund_status,
})
};
Ok(Self {
response,
..item.data
})
}
Expand All @@ -819,13 +840,18 @@ pub struct NoonRefundResponseTransactions {
}

#[derive(Default, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct NoonRefundSyncResponseResult {
transactions: Vec<NoonRefundResponseTransactions>,
}

#[derive(Default, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RefundSyncResponse {
result: NoonRefundSyncResponseResult,
result_code: u32,
class_description: String,
message: String,
}

impl TryFrom<types::RefundsResponseRouterData<api::RSync, RefundSyncResponse>>
Expand All @@ -849,12 +875,25 @@ impl TryFrom<types::RefundsResponseRouterData<api::RSync, RefundSyncResponse>>
})
})
.ok_or(errors::ConnectorError::ResponseHandlingFailed)?;

Ok(Self {
response: Ok(types::RefundsResponseData {
let refund_status = enums::RefundStatus::from(noon_transaction.status.to_owned());
let response = if is_refund_failure(refund_status) {
let response = &item.response;
Err(ErrorResponse {
status_code: item.http_code,
code: response.result_code.to_string(),
message: response.class_description.clone(),
reason: Some(response.message.clone()),
attempt_status: None,
connector_transaction_id: Some(noon_transaction.id.clone()),
})
} else {
Ok(types::RefundsResponseData {
connector_refund_id: noon_transaction.id.to_owned(),
refund_status: enums::RefundStatus::from(noon_transaction.status.to_owned()),
}),
refund_status,
})
};
Ok(Self {
response,
..item.data
})
}
Expand Down
66 changes: 47 additions & 19 deletions crates/router/src/connector/payme/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ use url::Url;

use crate::{
connector::utils::{
self, missing_field_err, AddressDetailsData, CardData, PaymentsAuthorizeRequestData,
PaymentsCompleteAuthorizeRequestData, PaymentsPreProcessingData, PaymentsSyncRequestData,
RouterData,
self, is_payment_failure, is_refund_failure, missing_field_err, AddressDetailsData,
CardData, PaymentsAuthorizeRequestData, PaymentsCompleteAuthorizeRequestData,
PaymentsPreProcessingData, PaymentsSyncRequestData, RouterData,
},
consts,
core::errors,
Expand Down Expand Up @@ -198,14 +198,15 @@ impl<F, T>
fn try_from(
item: types::ResponseRouterData<F, PaymePaySaleResponse, T, types::PaymentsResponseData>,
) -> Result<Self, Self::Error> {
let response = if item.response.sale_status == SaleStatus::Failed {
let status = enums::AttemptStatus::from(item.response.sale_status.clone());
let response = if is_payment_failure(status) {
// To populate error message in case of failure
Err(types::ErrorResponse::from((&item.response, item.http_code)))
} else {
Ok(types::PaymentsResponseData::try_from(&item.response)?)
};
Ok(Self {
status: enums::AttemptStatus::from(item.response.sale_status),
status,
response,
..item.data
})
Expand All @@ -227,7 +228,7 @@ impl From<(&PaymePaySaleResponse, u16)> for types::ErrorResponse {
reason: pay_sale_response.status_error_details.to_owned(),
status_code: http_code,
attempt_status: None,
connector_transaction_id: None,
connector_transaction_id: Some(pay_sale_response.payme_sale_id.clone()),
}
}
}
Expand Down Expand Up @@ -281,7 +282,8 @@ impl<F, T> TryFrom<types::ResponseRouterData<F, SaleQueryResponse, T, types::Pay
.first()
.cloned()
.ok_or(errors::ConnectorError::ResponseHandlingFailed)?;
let response = if transaction_response.sale_status == SaleStatus::Failed {
let status = enums::AttemptStatus::from(transaction_response.sale_status.clone());
let response = if is_payment_failure(status) {
// To populate error message in case of failure
Err(types::ErrorResponse::from((
&transaction_response,
Expand All @@ -291,7 +293,7 @@ impl<F, T> TryFrom<types::ResponseRouterData<F, SaleQueryResponse, T, types::Pay
Ok(types::PaymentsResponseData::from(&transaction_response))
};
Ok(Self {
status: enums::AttemptStatus::from(transaction_response.sale_status),
status,
response,
..item.data
})
Expand All @@ -312,7 +314,7 @@ impl From<(&SaleQuery, u16)> for types::ErrorResponse {
reason: sale_query_response.sale_error_text.clone(),
status_code: http_code,
attempt_status: None,
connector_transaction_id: None,
connector_transaction_id: Some(sale_query_response.sale_payme_id.clone()),
}
}
}
Expand Down Expand Up @@ -982,6 +984,7 @@ impl TryFrom<SaleStatus> for enums::RefundStatus {
pub struct PaymeRefundResponse {
sale_status: SaleStatus,
payme_transaction_id: String,
status_error_code: i64,
}

impl TryFrom<types::RefundsResponseRouterData<api::Execute, PaymeRefundResponse>>
Expand All @@ -991,11 +994,25 @@ impl TryFrom<types::RefundsResponseRouterData<api::Execute, PaymeRefundResponse>
fn try_from(
item: types::RefundsResponseRouterData<api::Execute, PaymeRefundResponse>,
) -> Result<Self, Self::Error> {
Ok(Self {
response: Ok(types::RefundsResponseData {
let refund_status = enums::RefundStatus::try_from(item.response.sale_status.clone())?;
let response = if is_refund_failure(refund_status) {
let payme_response = &item.response;
Err(types::ErrorResponse {
code: payme_response.status_error_code.to_string(),
message: payme_response.status_error_code.to_string(),
reason: Some(payme_response.status_error_code.to_string()),
status_code: item.http_code,
attempt_status: None,
connector_transaction_id: Some(payme_response.payme_transaction_id.clone()),
})
} else {
Ok(types::RefundsResponseData {
connector_refund_id: item.response.payme_transaction_id,
refund_status: enums::RefundStatus::try_from(item.response.sale_status)?,
}),
refund_status,
})
};
Ok(Self {
response,
..item.data
})
}
Expand Down Expand Up @@ -1031,13 +1048,24 @@ impl<F, T>
.items
.first()
.ok_or(errors::ConnectorError::ResponseHandlingFailed)?;
Ok(Self {
response: Ok(types::RefundsResponseData {
refund_status: enums::RefundStatus::try_from(
pay_sale_response.sale_status.clone(),
)?,
let refund_status = enums::RefundStatus::try_from(pay_sale_response.sale_status.clone())?;
let response = if is_refund_failure(refund_status) {
Err(types::ErrorResponse {
code: consts::NO_ERROR_CODE.to_string(),
message: consts::NO_ERROR_CODE.to_string(),
reason: None,
status_code: item.http_code,
attempt_status: None,
connector_transaction_id: Some(pay_sale_response.payme_transaction_id.clone()),
})
} else {
Ok(types::RefundsResponseData {
refund_status,
connector_refund_id: pay_sale_response.payme_transaction_id.clone(),
}),
})
};
Ok(Self {
response,
..item.data
})
}
Expand Down
1 change: 1 addition & 0 deletions crates/router/src/connector/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1786,6 +1786,7 @@ pub fn is_refund_failure(status: enums::RefundStatus) -> bool {
| common_enums::RefundStatus::Success => false,
}
}

#[cfg(test)]
mod error_code_error_message_tests {
#![allow(clippy::unwrap_used)]
Expand Down
Loading