mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-28 20:23:43 +08:00
fix(connector): [NMI] Handle empty response in psync and error response in complete authorize (#3548)
This commit is contained in:
@ -2,7 +2,7 @@ use api_models::webhooks;
|
||||
use cards::CardNumber;
|
||||
use common_utils::{errors::CustomResult, ext_traits::XmlExt};
|
||||
use error_stack::{IntoReport, Report, ResultExt};
|
||||
use masking::{ExposeInterface, Secret};
|
||||
use masking::{ExposeInterface, PeekInterface, Secret};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
@ -141,7 +141,7 @@ fn get_card_details(
|
||||
pub struct NmiVaultResponse {
|
||||
pub response: Response,
|
||||
pub responsetext: String,
|
||||
pub customer_vault_id: Option<String>,
|
||||
pub customer_vault_id: Option<Secret<String>>,
|
||||
pub response_code: String,
|
||||
pub transactionid: String,
|
||||
}
|
||||
@ -191,11 +191,14 @@ impl
|
||||
)?
|
||||
.to_string(),
|
||||
currency: currency_data,
|
||||
customer_vault_id: item.response.customer_vault_id.ok_or(
|
||||
errors::ConnectorError::MissingRequiredField {
|
||||
customer_vault_id: item
|
||||
.response
|
||||
.customer_vault_id
|
||||
.ok_or(errors::ConnectorError::MissingRequiredField {
|
||||
field_name: "customer_vault_id",
|
||||
},
|
||||
)?,
|
||||
})?
|
||||
.peek()
|
||||
.to_string(),
|
||||
public_key: auth_type.public_key.ok_or(
|
||||
errors::ConnectorError::InvalidConnectorConfig {
|
||||
config: "public_key",
|
||||
@ -237,40 +240,27 @@ pub struct NmiCompleteRequest {
|
||||
#[serde(rename = "type")]
|
||||
transaction_type: TransactionType,
|
||||
security_key: Secret<String>,
|
||||
orderid: String,
|
||||
orderid: Option<String>,
|
||||
ccnumber: CardNumber,
|
||||
ccexp: Secret<String>,
|
||||
cardholder_auth: CardHolderAuthType,
|
||||
cavv: String,
|
||||
xid: String,
|
||||
three_ds_version: Option<ThreeDsVersion>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum CardHolderAuthType {
|
||||
Verified,
|
||||
Attempted,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub enum ThreeDsVersion {
|
||||
#[serde(rename = "2.0.0")]
|
||||
VersionTwo,
|
||||
#[serde(rename = "2.1.0")]
|
||||
VersionTwoPointOne,
|
||||
#[serde(rename = "2.2.0")]
|
||||
VersionTwoPointTwo,
|
||||
cardholder_auth: Option<String>,
|
||||
cavv: Option<String>,
|
||||
xid: Option<String>,
|
||||
eci: Option<String>,
|
||||
three_ds_version: Option<String>,
|
||||
directory_server_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct NmiRedirectResponseData {
|
||||
cavv: String,
|
||||
xid: String,
|
||||
card_holder_auth: CardHolderAuthType,
|
||||
three_ds_version: Option<ThreeDsVersion>,
|
||||
order_id: String,
|
||||
cavv: Option<String>,
|
||||
xid: Option<String>,
|
||||
eci: Option<String>,
|
||||
card_holder_auth: Option<String>,
|
||||
three_ds_version: Option<String>,
|
||||
order_id: Option<String>,
|
||||
directory_server_id: Option<String>,
|
||||
}
|
||||
|
||||
impl TryFrom<&NmiRouterData<&types::PaymentsCompleteAuthorizeRouterData>> for NmiCompleteRequest {
|
||||
@ -308,7 +298,9 @@ impl TryFrom<&NmiRouterData<&types::PaymentsCompleteAuthorizeRouterData>> for Nm
|
||||
cardholder_auth: three_ds_data.card_holder_auth,
|
||||
cavv: three_ds_data.cavv,
|
||||
xid: three_ds_data.xid,
|
||||
eci: three_ds_data.eci,
|
||||
three_ds_version: three_ds_data.three_ds_version,
|
||||
directory_server_id: three_ds_data.directory_server_id,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -881,21 +873,22 @@ impl TryFrom<types::PaymentsSyncResponseRouterData<types::Response>>
|
||||
item: types::PaymentsSyncResponseRouterData<types::Response>,
|
||||
) -> Result<Self, Self::Error> {
|
||||
let response = SyncResponse::try_from(item.response.response.to_vec())?;
|
||||
Ok(Self {
|
||||
status: enums::AttemptStatus::from(NmiStatus::from(response.transaction.condition)),
|
||||
response: Ok(types::PaymentsResponseData::TransactionResponse {
|
||||
resource_id: types::ResponseId::ConnectorTransactionId(
|
||||
response.transaction.transaction_id,
|
||||
),
|
||||
redirection_data: None,
|
||||
mandate_reference: None,
|
||||
connector_metadata: None,
|
||||
network_txn_id: None,
|
||||
connector_response_reference_id: None,
|
||||
incremental_authorization_allowed: None,
|
||||
match response.transaction {
|
||||
Some(trn) => Ok(Self {
|
||||
status: enums::AttemptStatus::from(NmiStatus::from(trn.condition)),
|
||||
response: Ok(types::PaymentsResponseData::TransactionResponse {
|
||||
resource_id: types::ResponseId::ConnectorTransactionId(trn.transaction_id),
|
||||
redirection_data: None,
|
||||
mandate_reference: None,
|
||||
connector_metadata: None,
|
||||
network_txn_id: None,
|
||||
connector_response_reference_id: None,
|
||||
incremental_authorization_allowed: None,
|
||||
}),
|
||||
..item.data
|
||||
}),
|
||||
..item.data
|
||||
})
|
||||
None => Ok(Self { ..item.data }), //when there is empty connector response i.e. response we get in psync when payment status is in authentication_pending
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1081,7 +1074,7 @@ pub struct SyncTransactionResponse {
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct SyncResponse {
|
||||
pub transaction: SyncTransactionResponse,
|
||||
pub transaction: Option<SyncTransactionResponse>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
@ -1199,10 +1192,10 @@ pub struct NmiWebhookObject {
|
||||
impl TryFrom<&NmiWebhookBody> for SyncResponse {
|
||||
type Error = Error;
|
||||
fn try_from(item: &NmiWebhookBody) -> Result<Self, Self::Error> {
|
||||
let transaction = SyncTransactionResponse {
|
||||
let transaction = Some(SyncTransactionResponse {
|
||||
transaction_id: item.event_body.transaction_id.to_owned(),
|
||||
condition: item.event_body.condition.to_owned(),
|
||||
};
|
||||
});
|
||||
|
||||
Ok(Self { transaction })
|
||||
}
|
||||
|
||||
@ -1715,6 +1715,18 @@ pub fn build_redirection_form(
|
||||
item2.value=e.xid;
|
||||
responseForm.appendChild(item2);
|
||||
|
||||
var item6=document.createElement('input');
|
||||
item6.type='hidden';
|
||||
item6.name='eci';
|
||||
item6.value=e.eci;
|
||||
responseForm.appendChild(item6);
|
||||
|
||||
var item7=document.createElement('input');
|
||||
item7.type='hidden';
|
||||
item7.name='directoryServerId';
|
||||
item7.value=e.directoryServerId;
|
||||
responseForm.appendChild(item7);
|
||||
|
||||
var item3=document.createElement('input');
|
||||
item3.type='hidden';
|
||||
item3.name='cardHolderAuth';
|
||||
|
||||
Reference in New Issue
Block a user