Skip to content

Commit 80206ee

Browse files
fix(connector): [jpmorgan] 5xx during payment authorize and cancellation_reason (#8282)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
1 parent dab4058 commit 80206ee

File tree

4 files changed

+410
-9
lines changed

4 files changed

+410
-9
lines changed

crates/hyperswitch_connectors/src/connectors/jpmorgan.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,16 @@ impl ConnectorIntegration<AccessTokenAuth, AccessTokenRequestData, AccessToken>
306306
impl ConnectorIntegration<SetupMandate, SetupMandateRequestData, PaymentsResponseData>
307307
for Jpmorgan
308308
{
309+
fn build_request(
310+
&self,
311+
_req: &RouterData<SetupMandate, SetupMandateRequestData, PaymentsResponseData>,
312+
_connectors: &Connectors,
313+
) -> CustomResult<Option<Request>, errors::ConnectorError> {
314+
Err(
315+
errors::ConnectorError::NotImplemented("Setup Mandate flow for JPMorgan".to_string())
316+
.into(),
317+
)
318+
}
309319
}
310320

311321
impl ConnectorIntegration<Authorize, PaymentsAuthorizeData, PaymentsResponseData> for Jpmorgan {

crates/hyperswitch_connectors/src/connectors/jpmorgan/transformers.rs

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
use std::str::FromStr;
2+
13
use common_enums::enums::CaptureMethod;
24
use common_utils::types::MinorUnit;
5+
use error_stack::{report, ResultExt};
36
use hyperswitch_domain_models::{
47
payment_method_data::PaymentMethodData,
58
router_data::{AccessToken, ConnectorAuthType, RouterData},
@@ -12,7 +15,7 @@ use hyperswitch_domain_models::{
1215
},
1316
};
1417
use hyperswitch_interfaces::errors;
15-
use masking::Secret;
18+
use masking::{PeekInterface, Secret};
1619
use serde::{Deserialize, Serialize};
1720

1821
use crate::{
@@ -102,8 +105,8 @@ pub struct JpmorganPaymentMethodType {
102105
#[derive(Default, Debug, Serialize, Deserialize)]
103106
#[serde(rename_all = "camelCase")]
104107
pub struct Expiry {
105-
month: Secret<String>,
106-
year: Secret<String>,
108+
month: Secret<i32>,
109+
year: Secret<i32>,
107110
}
108111

109112
#[derive(Serialize, Debug, Default, Deserialize)]
@@ -159,8 +162,15 @@ impl TryFrom<&JpmorganRouterData<&PaymentsAuthorizeRouterData>> for JpmorganPaym
159162
let merchant = JpmorganMerchant { merchant_software };
160163

161164
let expiry: Expiry = Expiry {
162-
month: req_card.card_exp_month.clone(),
163-
year: req_card.get_expiry_year_4_digit(),
165+
month: Secret::new(
166+
req_card
167+
.card_exp_month
168+
.peek()
169+
.clone()
170+
.parse::<i32>()
171+
.change_context(errors::ConnectorError::RequestEncodingFailed)?,
172+
),
173+
year: req_card.get_expiry_year_as_4_digit_i32()?,
164174
};
165175

166176
let account_number = Secret::new(req_card.card_number.to_string());
@@ -637,12 +647,47 @@ impl TryFrom<RefundsResponseRouterData<RSync, JpmorganRefundSyncResponse>>
637647
}
638648
}
639649

650+
#[derive(Debug, Serialize, Deserialize)]
651+
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
652+
pub enum ReversalReason {
653+
NoResponse,
654+
LateResponse,
655+
UnableToDeliver,
656+
CardDeclined,
657+
MacNotVerified,
658+
MacSyncError,
659+
ZekSyncError,
660+
SystemMalfunction,
661+
SuspectedFraud,
662+
}
663+
664+
impl FromStr for ReversalReason {
665+
type Err = error_stack::Report<errors::ConnectorError>;
666+
667+
fn from_str(s: &str) -> Result<Self, Self::Err> {
668+
match s.to_uppercase().as_str() {
669+
"NO_RESPONSE" => Ok(Self::NoResponse),
670+
"LATE_RESPONSE" => Ok(Self::LateResponse),
671+
"UNABLE_TO_DELIVER" => Ok(Self::UnableToDeliver),
672+
"CARD_DECLINED" => Ok(Self::CardDeclined),
673+
"MAC_NOT_VERIFIED" => Ok(Self::MacNotVerified),
674+
"MAC_SYNC_ERROR" => Ok(Self::MacSyncError),
675+
"ZEK_SYNC_ERROR" => Ok(Self::ZekSyncError),
676+
"SYSTEM_MALFUNCTION" => Ok(Self::SystemMalfunction),
677+
"SUSPECTED_FRAUD" => Ok(Self::SuspectedFraud),
678+
_ => Err(report!(errors::ConnectorError::InvalidDataFormat {
679+
field_name: "cancellation_reason",
680+
})),
681+
}
682+
}
683+
}
684+
640685
#[derive(Debug, Serialize, Deserialize)]
641686
#[serde(rename_all = "camelCase")]
642687
pub struct JpmorganCancelRequest {
643688
pub amount: Option<i64>,
644689
pub is_void: Option<bool>,
645-
pub reversal_reason: Option<String>,
690+
pub reversal_reason: Option<ReversalReason>,
646691
}
647692

648693
impl TryFrom<JpmorganRouterData<&PaymentsCancelRouterData>> for JpmorganCancelRequest {
@@ -651,7 +696,13 @@ impl TryFrom<JpmorganRouterData<&PaymentsCancelRouterData>> for JpmorganCancelRe
651696
Ok(Self {
652697
amount: item.router_data.request.amount,
653698
is_void: Some(true),
654-
reversal_reason: item.router_data.request.cancellation_reason.clone(),
699+
reversal_reason: item
700+
.router_data
701+
.request
702+
.cancellation_reason
703+
.as_ref()
704+
.map(|reason| ReversalReason::from_str(reason))
705+
.transpose()?,
655706
})
656707
}
657708
}

0 commit comments

Comments
 (0)