Skip to content

Commit

Permalink
feat(connector): [Deutschebank] Implement Card 3ds (juspay#6844)
Browse files Browse the repository at this point in the history
Co-authored-by: Debarshi Gupta <[email protected]>
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Jan 13, 2025
1 parent 6a1f5a8 commit ac75335
Show file tree
Hide file tree
Showing 8 changed files with 990 additions and 111 deletions.
4 changes: 4 additions & 0 deletions crates/diesel_models/src/payment_attempt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3426,6 +3426,10 @@ pub enum RedirectForm {
access_token: String,
step_up_url: String,
},
DeutschebankThreeDSChallengeFlow {
acs_url: String,
creq: String,
},
Payme,
Braintree {
client_token: String,
Expand Down
77 changes: 59 additions & 18 deletions crates/hyperswitch_connectors/src/connectors/deutschebank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ use crate::{
types::ResponseRouterData,
utils::{
self, PaymentsAuthorizeRequestData, PaymentsCompleteAuthorizeRequestData,
RefundsRequestData,
RefundsRequestData, RouterData as ConnectorRouterData,
},
};

Expand Down Expand Up @@ -131,7 +131,7 @@ impl ConnectorCommon for Deutschebank {
}

fn get_currency_unit(&self) -> api::CurrencyUnit {
api::CurrencyUnit::Base
api::CurrencyUnit::Minor
}

fn common_get_content_type(&self) -> &'static str {
Expand Down Expand Up @@ -311,18 +311,30 @@ impl ConnectorIntegration<Authorize, PaymentsAuthorizeData, PaymentsResponseData
req: &PaymentsAuthorizeRouterData,
connectors: &Connectors,
) -> CustomResult<String, errors::ConnectorError> {
if req.request.connector_mandate_id().is_none() {
let event_id = req.connector_request_reference_id.clone();
let tx_action = if req.request.is_auto_capture()? {
"authorization"
} else {
"preauthorization"
};

if req.is_three_ds() && req.request.is_card() {
Ok(format!(
"{}/services/v2.1/headless3DSecure/event/{event_id}/{tx_action}/initialize",
self.base_url(connectors)
))
} else if !req.is_three_ds() && req.request.is_card() {
Err(errors::ConnectorError::NotSupported {
message: "Non-ThreeDs".to_owned(),
connector: "deutschebank",
}
.into())
} else if req.request.connector_mandate_id().is_none() {
Ok(format!(
"{}/services/v2.1/managedmandate",
self.base_url(connectors)
))
} else {
let event_id = req.connector_request_reference_id.clone();
let tx_action = if req.request.is_auto_capture()? {
"authorization"
} else {
"preauthorization"
};
Ok(format!(
"{}/services/v2.1/payment/event/{event_id}/directdebit/{tx_action}",
self.base_url(connectors)
Expand Down Expand Up @@ -375,7 +387,19 @@ impl ConnectorIntegration<Authorize, PaymentsAuthorizeData, PaymentsResponseData
event_builder: Option<&mut ConnectorEvent>,
res: Response,
) -> CustomResult<PaymentsAuthorizeRouterData, errors::ConnectorError> {
if data.request.connector_mandate_id().is_none() {
if data.is_three_ds() && data.request.is_card() {
let response: deutschebank::DeutschebankThreeDSInitializeResponse = res
.response
.parse_struct("DeutschebankPaymentsAuthorizeResponse")
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
event_builder.map(|i| i.set_response_body(&response));
router_env::logger::info!(connector_response=?response);
RouterData::try_from(ResponseRouterData {
response,
data: data.clone(),
http_code: res.status_code,
})
} else if data.request.connector_mandate_id().is_none() {
let response: deutschebank::DeutschebankMandatePostResponse = res
.response
.parse_struct("DeutschebankMandatePostResponse")
Expand Down Expand Up @@ -437,10 +461,18 @@ impl ConnectorIntegration<CompleteAuthorize, CompleteAuthorizeData, PaymentsResp
} else {
"preauthorization"
};
Ok(format!(
"{}/services/v2.1/payment/event/{event_id}/directdebit/{tx_action}",
self.base_url(connectors)
))

if req.is_three_ds() && matches!(req.payment_method, enums::PaymentMethod::Card) {
Ok(format!(
"{}/services/v2.1//headless3DSecure/event/{event_id}/final",
self.base_url(connectors)
))
} else {
Ok(format!(
"{}/services/v2.1/payment/event/{event_id}/directdebit/{tx_action}",
self.base_url(connectors)
))
}
}

fn get_request_body(
Expand All @@ -453,10 +485,9 @@ impl ConnectorIntegration<CompleteAuthorize, CompleteAuthorizeData, PaymentsResp
req.request.minor_amount,
req.request.currency,
)?;

let connector_router_data = deutschebank::DeutschebankRouterData::from((amount, req));
let connector_req =
deutschebank::DeutschebankDirectDebitRequest::try_from(&connector_router_data)?;
deutschebank::DeutschebankCompleteAuthorizeRequest::try_from(&connector_router_data)?;
Ok(RequestContent::Json(Box::new(connector_req)))
}

Expand Down Expand Up @@ -952,10 +983,20 @@ lazy_static! {
deutschebank_supported_payment_methods.add(
enums::PaymentMethod::BankDebit,
enums::PaymentMethodType::Sepa,
PaymentMethodDetails{
mandates: enums::FeatureStatus::Supported,
refunds: enums::FeatureStatus::Supported,
supported_capture_methods: supported_capture_methods.clone(),
}
);

deutschebank_supported_payment_methods.add(
enums::PaymentMethod::Card,
enums::PaymentMethodType::Credit,
PaymentMethodDetails{
mandates: enums::FeatureStatus::NotSupported,
refunds: enums::FeatureStatus::NotSupported,
supported_capture_methods,
refunds: enums::FeatureStatus::Supported,
supported_capture_methods: supported_capture_methods.clone(),
}
);

Expand Down
Loading

0 comments on commit ac75335

Please sign in to comment.