Skip to content

Commit 00e913c

Browse files
feat(connector): [DEUTSCHEBANK] Implement SEPA recurring payments (#5925)
1 parent dccb8d4 commit 00e913c

File tree

34 files changed

+300
-68
lines changed

34 files changed

+300
-68
lines changed

crates/api_models/src/payments.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,6 +1042,7 @@ pub struct ConnectorMandateReferenceId {
10421042
pub connector_mandate_id: Option<String>,
10431043
pub payment_method_id: Option<String>,
10441044
pub update_history: Option<Vec<UpdateHistory>>,
1045+
pub mandate_metadata: Option<serde_json::Value>,
10451046
}
10461047

10471048
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Eq, PartialEq)]

crates/hyperswitch_connectors/src/connectors/deutschebank.rs

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,10 @@ use transformers as deutschebank;
5050
use crate::{
5151
constants::headers,
5252
types::ResponseRouterData,
53-
utils::{self, PaymentsCompleteAuthorizeRequestData, RefundsRequestData},
53+
utils::{
54+
self, PaymentsAuthorizeRequestData, PaymentsCompleteAuthorizeRequestData,
55+
RefundsRequestData,
56+
},
5457
};
5558

5659
#[derive(Clone)]
@@ -182,6 +185,16 @@ impl ConnectorValidation for Deutschebank {
182185
),
183186
}
184187
}
188+
189+
fn validate_mandate_payment(
190+
&self,
191+
pm_type: Option<enums::PaymentMethodType>,
192+
pm_data: hyperswitch_domain_models::payment_method_data::PaymentMethodData,
193+
) -> CustomResult<(), errors::ConnectorError> {
194+
let mandate_supported_pmd =
195+
std::collections::HashSet::from([utils::PaymentMethodDataType::SepaBankDebit]);
196+
utils::is_mandate_supported(pm_data, pm_type, mandate_supported_pmd, self.id())
197+
}
185198
}
186199

187200
impl ConnectorIntegration<Session, PaymentsSessionData, PaymentsResponseData> for Deutschebank {
@@ -302,13 +315,26 @@ impl ConnectorIntegration<Authorize, PaymentsAuthorizeData, PaymentsResponseData
302315

303316
fn get_url(
304317
&self,
305-
_req: &PaymentsAuthorizeRouterData,
318+
req: &PaymentsAuthorizeRouterData,
306319
connectors: &Connectors,
307320
) -> CustomResult<String, errors::ConnectorError> {
308-
Ok(format!(
309-
"{}/services/v2.1/managedmandate",
310-
self.base_url(connectors)
311-
))
321+
if req.request.connector_mandate_id().is_none() {
322+
Ok(format!(
323+
"{}/services/v2.1/managedmandate",
324+
self.base_url(connectors)
325+
))
326+
} else {
327+
let event_id = req.connector_request_reference_id.clone();
328+
let tx_action = if req.request.is_auto_capture()? {
329+
"authorization"
330+
} else {
331+
"preauthorization"
332+
};
333+
Ok(format!(
334+
"{}/services/v2.1/payment/event/{event_id}/directdebit/{tx_action}",
335+
self.base_url(connectors)
336+
))
337+
}
312338
}
313339

314340
fn get_request_body(
@@ -356,17 +382,31 @@ impl ConnectorIntegration<Authorize, PaymentsAuthorizeData, PaymentsResponseData
356382
event_builder: Option<&mut ConnectorEvent>,
357383
res: Response,
358384
) -> CustomResult<PaymentsAuthorizeRouterData, errors::ConnectorError> {
359-
let response: deutschebank::DeutschebankMandatePostResponse = res
360-
.response
361-
.parse_struct("Deutschebank PaymentsAuthorizeResponse")
362-
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
363-
event_builder.map(|i| i.set_response_body(&response));
364-
router_env::logger::info!(connector_response=?response);
365-
RouterData::try_from(ResponseRouterData {
366-
response,
367-
data: data.clone(),
368-
http_code: res.status_code,
369-
})
385+
if data.request.connector_mandate_id().is_none() {
386+
let response: deutschebank::DeutschebankMandatePostResponse = res
387+
.response
388+
.parse_struct("DeutschebankMandatePostResponse")
389+
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
390+
event_builder.map(|i| i.set_response_body(&response));
391+
router_env::logger::info!(connector_response=?response);
392+
RouterData::try_from(ResponseRouterData {
393+
response,
394+
data: data.clone(),
395+
http_code: res.status_code,
396+
})
397+
} else {
398+
let response: deutschebank::DeutschebankPaymentsResponse = res
399+
.response
400+
.parse_struct("DeutschebankPaymentsAuthorizeResponse")
401+
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
402+
event_builder.map(|i| i.set_response_body(&response));
403+
router_env::logger::info!(connector_response=?response);
404+
RouterData::try_from(ResponseRouterData {
405+
response,
406+
data: data.clone(),
407+
http_code: res.status_code,
408+
})
409+
}
370410
}
371411

372412
fn get_error_response(

0 commit comments

Comments
 (0)