refactor(connector): [NMI] Include mandatory fields for card 3DS (#3203)

This commit is contained in:
Sakil Mostak
2023-12-26 17:36:33 +05:30
committed by GitHub
parent c7e15aee9d
commit a46b8a7b05
6 changed files with 80 additions and 7 deletions

View File

@ -1450,7 +1450,25 @@ impl Default for super::settings::RequiredFields {
field_type: enums::FieldType::UserCardCvc,
value: None,
}
)
),
(
"billing.address.first_name".to_string(),
RequiredFieldInfo {
required_field: "billing.address.first_name".to_string(),
display_name: "billing_first_name".to_string(),
field_type: enums::FieldType::UserBillingName,
value: None,
}
),
(
"billing.address.last_name".to_string(),
RequiredFieldInfo {
required_field: "billing.address.last_name".to_string(),
display_name: "billing_last_name".to_string(),
field_type: enums::FieldType::UserBillingName,
value: None,
}
),
]
),
common: HashMap::new(),
@ -3481,7 +3499,25 @@ impl Default for super::settings::RequiredFields {
field_type: enums::FieldType::UserCardCvc,
value: None,
}
)
),
(
"billing.address.first_name".to_string(),
RequiredFieldInfo {
required_field: "billing.address.first_name".to_string(),
display_name: "billing_first_name".to_string(),
field_type: enums::FieldType::UserBillingName,
value: None,
}
),
(
"billing.address.last_name".to_string(),
RequiredFieldInfo {
required_field: "billing.address.last_name".to_string(),
display_name: "billing_last_name".to_string(),
field_type: enums::FieldType::UserBillingName,
value: None,
}
),
]
),
common: HashMap::new(),

View File

@ -6,7 +6,10 @@ use masking::{ExposeInterface, Secret};
use serde::{Deserialize, Serialize};
use crate::{
connector::utils::{self, PaymentsAuthorizeRequestData, PaymentsCompleteAuthorizeRequestData},
connector::utils::{
self, AddressDetailsData, PaymentsAuthorizeRequestData,
PaymentsCompleteAuthorizeRequestData, RouterData,
},
core::errors,
services,
types::{self, api, storage::enums, transformers::ForeignFrom, ConnectorAuthType},
@ -83,6 +86,9 @@ pub struct NmiVaultRequest {
security_key: Secret<String>,
ccnumber: CardNumber,
ccexp: Secret<String>,
cvv: Secret<String>,
first_name: Secret<String>,
last_name: Secret<String>,
customer_vault: CustomerAction,
}
@ -97,12 +103,16 @@ impl TryFrom<&types::PaymentsPreProcessingRouterData> for NmiVaultRequest {
type Error = Error;
fn try_from(item: &types::PaymentsPreProcessingRouterData) -> Result<Self, Self::Error> {
let auth_type: NmiAuthType = (&item.connector_auth_type).try_into()?;
let (ccnumber, ccexp) = get_card_details(item.request.payment_method_data.clone())?;
let (ccnumber, ccexp, cvv) = get_card_details(item.request.payment_method_data.clone())?;
let billing_details = item.get_billing_address()?;
Ok(Self {
security_key: auth_type.api_key,
ccnumber,
ccexp,
cvv,
first_name: billing_details.get_first_name()?.to_owned(),
last_name: billing_details.get_last_name()?.to_owned(),
customer_vault: CustomerAction::AddCustomer,
})
}
@ -110,7 +120,7 @@ impl TryFrom<&types::PaymentsPreProcessingRouterData> for NmiVaultRequest {
fn get_card_details(
payment_method_data: Option<api::PaymentMethodData>,
) -> CustomResult<(CardNumber, Secret<String>), errors::ConnectorError> {
) -> CustomResult<(CardNumber, Secret<String>, Secret<String>), errors::ConnectorError> {
match payment_method_data {
Some(api::PaymentMethodData::Card(ref card_details)) => Ok((
card_details.card_number.clone(),
@ -118,6 +128,7 @@ fn get_card_details(
card_details,
"".to_string(),
),
card_details.card_cvc.clone(),
)),
_ => Err(errors::ConnectorError::NotImplemented(
utils::get_unimplemented_payment_method_error_message("Nmi"),
@ -189,6 +200,7 @@ impl
config: "public_key",
},
)?,
order_id: item.data.connector_request_reference_id.clone(),
}),
mandate_reference: None,
connector_metadata: None,
@ -220,13 +232,17 @@ impl
#[derive(Debug, Serialize)]
pub struct NmiCompleteRequest {
amount: f64,
#[serde(rename = "type")]
transaction_type: TransactionType,
security_key: Secret<String>,
orderid: String,
ccnumber: CardNumber,
ccexp: Secret<String>,
cardholder_auth: CardHolderAuthType,
cavv: String,
xid: String,
three_ds_version: ThreeDsVersion,
three_ds_version: Option<ThreeDsVersion>,
}
#[derive(Debug, Serialize, Deserialize)]
@ -240,6 +256,8 @@ pub enum CardHolderAuthType {
pub enum ThreeDsVersion {
#[serde(rename = "2.0.0")]
VersionTwo,
#[serde(rename = "2.1.0")]
VersionTwoPointOne,
#[serde(rename = "2.2.0")]
VersionTwoPointTwo,
}
@ -250,7 +268,8 @@ pub struct NmiRedirectResponseData {
cavv: String,
xid: String,
card_holder_auth: CardHolderAuthType,
three_ds_version: ThreeDsVersion,
three_ds_version: Option<ThreeDsVersion>,
order_id: String,
}
impl TryFrom<&NmiRouterData<&types::PaymentsCompleteAuthorizeRouterData>> for NmiCompleteRequest {
@ -275,9 +294,16 @@ impl TryFrom<&NmiRouterData<&types::PaymentsCompleteAuthorizeRouterData>> for Nm
field_name: "three_ds_data",
})?;
let (ccnumber, ccexp, ..) =
get_card_details(item.router_data.request.payment_method_data.clone())?;
Ok(Self {
amount: item.amount,
transaction_type,
security_key: auth_type.api_key,
orderid: three_ds_data.order_id,
ccnumber,
ccexp,
cardholder_auth: three_ds_data.card_holder_auth,
cavv: three_ds_data.cavv,
xid: three_ds_data.xid,

View File

@ -778,6 +778,7 @@ pub enum RedirectForm {
currency: Currency,
public_key: Secret<String>,
customer_vault_id: String,
order_id: String,
},
}
@ -1507,6 +1508,7 @@ pub fn build_redirection_form(
currency,
public_key,
customer_vault_id,
order_id,
} => {
let public_key_val = public_key.peek();
maud::html! {
@ -1563,6 +1565,12 @@ pub fn build_redirection_form(
item4.value=e.threeDsVersion;
responseForm.appendChild(item4);
var item5=document.createElement('input');
item4.type='hidden';
item4.name='orderId';
item4.value='{order_id}';
responseForm.appendChild(item5);
document.body.appendChild(responseForm);
responseForm.submit();
}});