feat(connector): [DATATRANS] Add Support for External 3DS (#7226)

This commit is contained in:
awasthi21
2025-02-10 03:03:23 +05:30
committed by GitHub
parent df328c5e52
commit 45882bdb76
3 changed files with 47 additions and 11 deletions

View File

@ -416,12 +416,11 @@ impl Connector {
| Self::Razorpay
| Self::Riskified
| Self::Threedsecureio
| Self::Datatrans
| Self::Netcetera
| Self::CtpMastercard
| Self::Noon
| Self::Stripe => false,
Self::Checkout | Self::Nmi | Self::Cybersource => true,
Self::Checkout | Self::Nmi |Self::Datatrans|Self::Cybersource => true,
}
}

View File

@ -223,7 +223,7 @@ impl ConnectorIntegration<Authorize, PaymentsAuthorizeData, PaymentsResponseData
connectors: &Connectors,
) -> CustomResult<String, errors::ConnectorError> {
let base_url = self.base_url(connectors);
if req.is_three_ds() {
if req.is_three_ds() && req.request.authentication_data.is_none() {
Ok(format!("{base_url}v1/transactions"))
} else {
Ok(format!("{base_url}v1/transactions/authorize"))

View File

@ -136,7 +136,7 @@ pub struct PlainCardDetails {
pub cvv: Secret<String>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "3D")]
pub three_ds: Option<ThreedsInfo>,
pub three_ds: Option<ThreeDSecureData>,
}
#[derive(Serialize, Clone, Debug)]
@ -144,6 +144,26 @@ pub struct ThreedsInfo {
cardholder: CardHolder,
}
#[derive(Serialize, Clone, Debug)]
#[serde(untagged)]
pub enum ThreeDSecureData {
Cardholder(ThreedsInfo),
Authentication(ThreeDSData),
}
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ThreeDSData {
#[serde(rename = "threeDSTransactionId")]
pub three_ds_transaction_id: Secret<String>,
pub cavv: Secret<String>,
pub eci: Option<String>,
pub xid: Secret<String>,
#[serde(rename = "threeDSVersion")]
pub three_ds_version: String,
#[serde(rename = "authenticationResponse")]
pub authentication_response: String,
}
#[derive(Debug, Serialize, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CardHolder {
@ -240,13 +260,16 @@ impl TryFrom<&DatatransRouterData<&types::PaymentsAuthorizeRouterData>>
card: create_card_details(item, &req_card)?,
refno: item.router_data.connector_request_reference_id.clone(),
auto_settle: item.router_data.request.is_auto_capture()?,
redirect: match item.router_data.is_three_ds() {
true => Some(RedirectUrls {
redirect: if item.router_data.is_three_ds()
&& item.router_data.request.authentication_data.is_none()
{
Some(RedirectUrls {
success_url: item.router_data.request.router_return_url.clone(),
cancel_url: item.router_data.request.router_return_url.clone(),
error_url: item.router_data.request.router_return_url.clone(),
}),
false => None,
})
} else {
None
},
}),
PaymentMethodData::Wallet(_)
@ -314,9 +337,23 @@ fn create_card_details(
three_ds: None,
};
if item.router_data.is_three_ds() {
if let Some(auth_data) = &item.router_data.request.authentication_data {
details.three_ds = Some(ThreeDSecureData::Authentication(ThreeDSData {
three_ds_transaction_id: Secret::new(auth_data.threeds_server_transaction_id.clone()),
cavv: Secret::new(auth_data.cavv.clone()),
eci: auth_data.eci.clone(),
xid: Secret::new(
auth_data
.ds_trans_id
.clone()
.ok_or(errors::ConnectorError::MissingRequiredField { field_name: "xid" })?,
),
three_ds_version: auth_data.message_version.to_string(),
authentication_response: "Y".to_string(),
}));
} else if item.router_data.is_three_ds() {
let billing = item.router_data.get_billing_address()?;
details.three_ds = Some(ThreedsInfo {
details.three_ds = Some(ThreeDSecureData::Cardholder(ThreedsInfo {
cardholder: CardHolder {
cardholder_name: item.router_data.get_billing_full_name()?,
email: item.router_data.request.get_email()?,
@ -326,7 +363,7 @@ fn create_card_details(
bill_addr_state: billing.get_state().ok().cloned(),
bill_addr_country: billing.get_country().ok().copied(),
},
});
}));
}
Ok(details)
}