diff --git a/crates/router/src/connector/nmi.rs b/crates/router/src/connector/nmi.rs index e7b7e0e902..527403736a 100644 --- a/crates/router/src/connector/nmi.rs +++ b/crates/router/src/connector/nmi.rs @@ -8,10 +8,13 @@ use error_stack::{IntoReport, ResultExt}; use regex::Regex; use transformers as nmi; -use super::utils as connector_utils; +use super::utils::{self as connector_utils}; use crate::{ configs::settings, - core::errors::{self, CustomResult}, + core::{ + errors::{self, CustomResult}, + payments, + }, events::connector_api_logs::ConnectorEvent, services::{self, request, ConnectorIntegration, ConnectorValidation}, types::{ @@ -980,3 +983,41 @@ impl api::IncomingWebhook for Nmi { } } } + +impl services::ConnectorRedirectResponse for Nmi { + fn get_flow_type( + &self, + _query_params: &str, + json_payload: Option, + action: services::PaymentAction, + ) -> CustomResult { + match action { + services::PaymentAction::CompleteAuthorize => { + let payload_data = + json_payload.ok_or(errors::ConnectorError::MissingRequiredField { + field_name: "connector_metadata", + })?; + + let redirect_res: nmi::NmiRedirectResponse = serde_json::from_value(payload_data) + .into_report() + .change_context(errors::ConnectorError::MissingConnectorRedirectionPayload { + field_name: "redirect_res", + })?; + + match redirect_res { + transformers::NmiRedirectResponse::NmiRedirectResponseData(_) => { + Ok(payments::CallConnectorAction::Trigger) + } + transformers::NmiRedirectResponse::NmiErrorResponseData(error_res) => { + Ok(payments::CallConnectorAction::StatusUpdate { + status: enums::AttemptStatus::Failure, + error_code: Some(error_res.code), + error_message: Some(error_res.message), + }) + } + } + } + services::PaymentAction::PSync => Ok(payments::CallConnectorAction::Trigger), + } + } +} diff --git a/crates/router/src/connector/nmi/transformers.rs b/crates/router/src/connector/nmi/transformers.rs index e83142f8ef..2f8505522b 100644 --- a/crates/router/src/connector/nmi/transformers.rs +++ b/crates/router/src/connector/nmi/transformers.rs @@ -268,6 +268,20 @@ pub struct NmiCompleteRequest { three_ds_version: Option, directory_server_id: Option, } +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +#[serde(untagged)] +pub enum NmiRedirectResponse { + NmiRedirectResponseData(NmiRedirectResponseData), + NmiErrorResponseData(NmiErrorResponseData), +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct NmiErrorResponseData { + pub code: String, + pub message: String, +} #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] @@ -279,7 +293,7 @@ pub struct NmiRedirectResponseData { three_ds_version: Option, order_id: Option, directory_server_id: Option, - customer_vault_id: Option, + customer_vault_id: String, } impl TryFrom<&NmiRouterData<&types::PaymentsCompleteAuthorizeRouterData>> for NmiCompleteRequest { @@ -311,11 +325,7 @@ impl TryFrom<&NmiRouterData<&types::PaymentsCompleteAuthorizeRouterData>> for Nm transaction_type, security_key: auth_type.api_key, orderid: three_ds_data.order_id, - customer_vault_id: three_ds_data.customer_vault_id.ok_or( - errors::ConnectorError::MissingRequiredField { - field_name: "customer_vault_id", - }, - )?, + customer_vault_id: three_ds_data.customer_vault_id, email: item.router_data.request.email.clone(), cvv, cardholder_auth: three_ds_data.card_holder_auth, diff --git a/crates/router/src/core/payments/flows.rs b/crates/router/src/core/payments/flows.rs index ebc0cf3664..d69f668bf9 100644 --- a/crates/router/src/core/payments/flows.rs +++ b/crates/router/src/core/payments/flows.rs @@ -393,7 +393,6 @@ default_imp_for_connector_redirect_response!( connector::Klarna, connector::Multisafepay, connector::Nexinets, - connector::Nmi, connector::Opayo, connector::Opennode, connector::Payeezy, diff --git a/crates/router/src/services/api.rs b/crates/router/src/services/api.rs index bfba31c344..1023983466 100644 --- a/crates/router/src/services/api.rs +++ b/crates/router/src/services/api.rs @@ -1821,18 +1821,16 @@ pub fn build_redirection_form( amount: '{amount}' }}; - var responseForm = document.createElement('form'); - responseForm.action=window.location.pathname.replace(/payments\\/redirect\\/(\\w+)\\/(\\w+)\\/\\w+/, \"payments/$1/$2/redirect/complete/nmi\"); - responseForm.method='POST'; - const threeDSsecureInterface = threeDS.createUI(options); threeDSsecureInterface.on('challenge', function(e) {{ - console.log('Challenged'); document.getElementById('loader-wrapper').style.display = 'none'; }}); threeDSsecureInterface.on('complete', function(e) {{ + var responseForm = document.createElement('form'); + responseForm.action=window.location.pathname.replace(/payments\\/redirect\\/(\\w+)\\/(\\w+)\\/\\w+/, \"payments/$1/$2/redirect/complete/nmi\"); + responseForm.method='POST'; var item1=document.createElement('input'); item1.type='hidden'; @@ -1887,6 +1885,23 @@ pub fn build_redirection_form( }}); threeDSsecureInterface.on('failure', function(e) {{ + var responseForm = document.createElement('form'); + responseForm.action=window.location.pathname.replace(/payments\\/redirect\\/(\\w+)\\/(\\w+)\\/\\w+/, \"payments/$1/$2/redirect/complete/nmi\"); + responseForm.method='POST'; + + var error_code=document.createElement('input'); + error_code.type='hidden'; + error_code.name='code'; + error_code.value= e.code; + responseForm.appendChild(error_code); + + var error_message=document.createElement('input'); + error_message.type='hidden'; + error_message.name='message'; + error_message.value= e.message; + responseForm.appendChild(error_message); + + document.body.appendChild(responseForm); responseForm.submit(); }});