From 3e9aa7dd91bd6a5f95f4425083af8d17d7ef0167 Mon Sep 17 00:00:00 2001 From: deepanshu-iiitu Date: Tue, 17 Sep 2024 17:10:16 +0530 Subject: [PATCH 01/11] feat(connector): [DEUTSCHEBANK] Implement Mandate Payments --- crates/api_models/src/payments.rs | 1 + .../src/connectors/deutschebank.rs | 38 ++- .../connectors/deutschebank/transformers.rs | 147 ++++++++-- .../src/connectors/fiservemea/transformers.rs | 11 +- crates/hyperswitch_connectors/src/utils.rs | 271 +++++++++++++++++- .../src/router_data.rs | 1 + .../src/router_response_types.rs | 1 + crates/hyperswitch_interfaces/src/errors.rs | 2 + .../router/src/connector/aci/transformers.rs | 1 + .../src/connector/adyen/transformers.rs | 1 + .../connector/authorizedotnet/transformers.rs | 2 + .../src/connector/bamboraapac/transformers.rs | 2 + .../connector/bankofamerica/transformers.rs | 2 + .../src/connector/braintree/transformers.rs | 4 + .../src/connector/cybersource/transformers.rs | 2 + .../src/connector/globalpay/transformers.rs | 1 + .../src/connector/gocardless/transformers.rs | 2 + .../connector/multisafepay/transformers.rs | 1 + .../src/connector/nexinets/transformers.rs | 1 + .../router/src/connector/noon/transformers.rs | 1 + .../src/connector/nuvei/transformers.rs | 1 + .../src/connector/payeezy/transformers.rs | 1 + .../src/connector/payme/transformers.rs | 1 + .../src/connector/stripe/transformers.rs | 3 + .../src/connector/wellsfargo/transformers.rs | 2 + crates/router/src/core/errors/utils.rs | 3 + crates/router/src/core/payments.rs | 7 +- crates/router/src/core/payments/helpers.rs | 2 + .../payments/operations/payment_confirm.rs | 1 + .../payments/operations/payment_create.rs | 4 +- .../payments/operations/payment_response.rs | 14 +- .../payments/operations/payment_update.rs | 2 +- .../router/src/core/payments/tokenization.rs | 20 +- .../src/types/storage/payment_method.rs | 1 + 34 files changed, 495 insertions(+), 59 deletions(-) diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index abd795361bb8..27c7d20489a9 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -1034,6 +1034,7 @@ pub struct ConnectorMandateReferenceId { pub connector_mandate_id: Option, pub payment_method_id: Option, pub update_history: Option>, + pub mandate_metadata: Option, } #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Eq, PartialEq)] diff --git a/crates/hyperswitch_connectors/src/connectors/deutschebank.rs b/crates/hyperswitch_connectors/src/connectors/deutschebank.rs index 30e67babe898..5f38e3e830fc 100644 --- a/crates/hyperswitch_connectors/src/connectors/deutschebank.rs +++ b/crates/hyperswitch_connectors/src/connectors/deutschebank.rs @@ -50,7 +50,10 @@ use transformers as deutschebank; use crate::{ constants::headers, types::ResponseRouterData, - utils::{self, PaymentsCompleteAuthorizeRequestData, RefundsRequestData}, + utils::{ + self, PaymentsAuthorizeRequestData, PaymentsCompleteAuthorizeRequestData, + RefundsRequestData, + }, }; #[derive(Clone)] @@ -182,6 +185,16 @@ impl ConnectorValidation for Deutschebank { ), } } + + fn validate_mandate_payment( + &self, + pm_type: Option, + pm_data: hyperswitch_domain_models::payment_method_data::PaymentMethodData, + ) -> CustomResult<(), errors::ConnectorError> { + let mandate_supported_pmd = + std::collections::HashSet::from([utils::PaymentMethodDataType::SepaBankDebit]); + utils::is_mandate_supported(pm_data, pm_type, mandate_supported_pmd, self.id()) + } } impl ConnectorIntegration for Deutschebank { @@ -302,13 +315,26 @@ impl ConnectorIntegration CustomResult { - Ok(format!( - "{}/services/v2.1/managedmandate", - self.base_url(connectors) - )) + 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) + )) + } } fn get_request_body( diff --git a/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs b/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs index dc146dc38d4e..11517de7409d 100644 --- a/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs @@ -1,7 +1,8 @@ use std::collections::HashMap; use common_enums::enums; -use common_utils::{pii::Email, types::MinorUnit}; +use common_utils::{ext_traits::ValueExt, pii::Email, types::MinorUnit}; +use error_stack::ResultExt; use hyperswitch_domain_models::{ payment_method_data::{BankDebitData, PaymentMethodData}, router_data::{AccessToken, ConnectorAuthType, RouterData}, @@ -13,7 +14,9 @@ use hyperswitch_domain_models::{ CompleteAuthorizeData, PaymentsAuthorizeData, PaymentsCaptureData, PaymentsSyncData, ResponseId, }, - router_response_types::{PaymentsResponseData, RedirectForm, RefundsResponseData}, + router_response_types::{ + MandateReference, PaymentsResponseData, RedirectForm, RefundsResponseData, + }, types::{ PaymentsAuthorizeRouterData, PaymentsCancelRouterData, PaymentsCaptureRouterData, PaymentsCompleteAuthorizeRouterData, RefundsRouterData, @@ -26,8 +29,8 @@ use serde::{Deserialize, Serialize}; use crate::{ types::{PaymentsCancelResponseRouterData, RefundsResponseRouterData, ResponseRouterData}, utils::{ - AddressDetailsData, PaymentsAuthorizeRequestData, PaymentsCompleteAuthorizeRequestData, - RefundsRequestData, RouterData as OtherRouterData, + self, AddressDetailsData, PaymentsAuthorizeRequestData, + PaymentsCompleteAuthorizeRequestData, RefundsRequestData, RouterData as OtherRouterData, }, }; @@ -113,7 +116,7 @@ pub enum DeutschebankSEPAApproval { } #[derive(Debug, Serialize, PartialEq)] -pub struct DeutschebankPaymentsRequest { +pub struct DeutschebankMandatePostRequest { approval_by: DeutschebankSEPAApproval, email_address: Email, iban: Secret, @@ -121,6 +124,13 @@ pub struct DeutschebankPaymentsRequest { last_name: Secret, } +#[derive(Debug, Serialize)] +#[serde(untagged)] +pub enum DeutschebankPaymentsRequest { + MandatePost(DeutschebankMandatePostRequest), + DirectDebit(DeutschebankDirectDebitRequest), +} + impl TryFrom<&DeutschebankRouterData<&PaymentsAuthorizeRouterData>> for DeutschebankPaymentsRequest { @@ -128,16 +138,62 @@ impl TryFrom<&DeutschebankRouterData<&PaymentsAuthorizeRouterData>> fn try_from( item: &DeutschebankRouterData<&PaymentsAuthorizeRouterData>, ) -> Result { - let billing_address = item.router_data.get_billing_address()?; - match item.router_data.request.payment_method_data.clone() { - PaymentMethodData::BankDebit(BankDebitData::SepaBankDebit { iban, .. }) => Ok(Self { - approval_by: DeutschebankSEPAApproval::Click, - email_address: item.router_data.request.get_email()?, - iban, - first_name: billing_address.get_first_name()?.clone(), - last_name: billing_address.get_last_name()?.clone(), - }), - _ => Err(errors::ConnectorError::NotImplemented("Payment methods".to_string()).into()), + match item + .router_data + .request + .mandate_id + .clone() + .and_then(|mandate_id| mandate_id.mandate_reference_id) + { + None => { + let billing_address = item.router_data.get_billing_address()?; + match item.router_data.request.payment_method_data.clone() { + PaymentMethodData::BankDebit(BankDebitData::SepaBankDebit { iban, .. }) => { + Ok(Self::MandatePost(DeutschebankMandatePostRequest { + approval_by: DeutschebankSEPAApproval::Click, + email_address: item.router_data.request.get_email()?, + iban, + first_name: billing_address.get_first_name()?.clone(), + last_name: billing_address.get_last_name()?.clone(), + })) + } + _ => Err(errors::ConnectorError::NotImplemented( + utils::get_unimplemented_payment_method_error_message("deutschebank"), + ) + .into()), + } + } + Some(api_models::payments::MandateReferenceId::ConnectorMandateId(mandate_data)) => { + let mandate_metadata: DeutschebankMandateMetadata = mandate_data + .mandate_metadata + .ok_or(errors::ConnectorError::MissingConnectorMandateMetadata)? + .peek() + .clone() + .parse_value("DeutschebankMandateMetadata") + .change_context(errors::ConnectorError::ParsingFailed)?; + Ok(Self::DirectDebit(DeutschebankDirectDebitRequest { + amount_total: DeutschebankAmount { + amount: item.amount, + currency: item.router_data.request.currency, + }, + means_of_payment: DeutschebankMeansOfPayment { + bank_account: DeutschebankBankAccount { + account_holder: mandate_metadata.account_holder, + iban: mandate_metadata.iban, + }, + }, + mandate: DeutschebankMandate { + reference: mandate_metadata.reference, + signed_on: mandate_metadata.signed_on, + }, + })) + } + Some(api_models::payments::MandateReferenceId::NetworkMandateId(_)) => { + Err(errors::ConnectorError::NotImplemented( + utils::get_unimplemented_payment_method_error_message("deutschebank"), + ) + .into()) + } } } } @@ -176,6 +232,14 @@ impl From for common_enums::AttemptStatus { } } +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct DeutschebankMandateMetadata { + account_holder: Secret, + iban: Secret, + reference: Secret, + signed_on: String, +} + #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct DeutschebankMandatePostResponse { rc: String, @@ -207,14 +271,14 @@ impl PaymentsResponseData, >, ) -> Result { - let signed_on = match item.response.approval_date { + let signed_on = match item.response.approval_date.clone() { Some(date) => date.chars().take(10).collect(), None => time::OffsetDateTime::now_utc().date().to_string(), }; - match item.response.reference { + match item.response.reference.clone() { Some(reference) => Ok(Self { status: if item.response.rc == "0" { - match item.response.state { + match item.response.state.clone() { Some(state) => common_enums::AttemptStatus::from(state), None => common_enums::AttemptStatus::Failure, } @@ -227,11 +291,31 @@ impl endpoint: item.data.request.get_complete_authorize_url()?, method: common_utils::request::Method::Get, form_fields: HashMap::from([ - ("reference".to_string(), reference), - ("signed_on".to_string(), signed_on), + ("reference".to_string(), reference.clone()), + ("signed_on".to_string(), signed_on.clone()), ]), }), - mandate_reference: None, + mandate_reference: Some(MandateReference { + connector_mandate_id: item.response.mandate_id, + payment_method_id: None, + mandate_metadata: Some( + serde_json::json!(DeutschebankMandateMetadata { + account_holder: item.data.get_billing_address()?.get_full_name()?, + iban: match item.data.request.payment_method_data.clone() { + PaymentMethodData::BankDebit( + BankDebitData::SepaBankDebit { iban, .. }, + ) => Ok(iban), + _ => Err(errors::ConnectorError::MissingRequiredField { + field_name: + "payment_method_data.bank_debit.sepa_bank_debit.iban" + }), + }?, + reference: Secret::from(reference), + signed_on, + }) + .into(), + ), + }), connector_metadata: None, network_txn_id: None, connector_response_reference_id: None, @@ -268,7 +352,7 @@ pub struct DeutschebankBankAccount { #[derive(Debug, Serialize, PartialEq)] pub struct DeutschebankMandate { reference: Secret, - signed_on: Secret, + signed_on: String, } #[derive(Debug, Serialize, PartialEq)] @@ -319,14 +403,12 @@ impl TryFrom<&DeutschebankRouterData<&PaymentsCompleteAuthorizeRouterData>> })? .to_owned(), ); - let signed_on = Secret::from( - queries_params - .get("signed_on") - .ok_or(errors::ConnectorError::MissingRequiredField { - field_name: "signed_on", - })? - .to_owned(), - ); + let signed_on = queries_params + .get("signed_on") + .ok_or(errors::ConnectorError::MissingRequiredField { + field_name: "signed_on", + })? + .to_owned(); match item.router_data.request.payment_method_data.clone() { Some(PaymentMethodData::BankDebit(BankDebitData::SepaBankDebit { iban, .. })) => { @@ -349,7 +431,10 @@ impl TryFrom<&DeutschebankRouterData<&PaymentsCompleteAuthorizeRouterData>> }, }) } - _ => Err(errors::ConnectorError::NotImplemented("Payment methods".to_string()).into()), + _ => Err(errors::ConnectorError::NotImplemented( + utils::get_unimplemented_payment_method_error_message("deutschebank"), + ) + .into()), } } } diff --git a/crates/hyperswitch_connectors/src/connectors/fiservemea/transformers.rs b/crates/hyperswitch_connectors/src/connectors/fiservemea/transformers.rs index fdec3d0e1ebe..7f88903e8670 100644 --- a/crates/hyperswitch_connectors/src/connectors/fiservemea/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/fiservemea/transformers.rs @@ -170,13 +170,6 @@ pub enum ResponseType { UnsupportedMediaType, } -#[derive(Debug, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub enum FiservemeaResponseType { - TransactionResponse, - ErrorResponse, -} - #[derive(Debug, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] pub enum FiservemeaTransactionType { @@ -329,7 +322,7 @@ fn map_status( pub struct FiservemeaPaymentsResponse { response_type: Option, #[serde(rename = "type")] - fiservemea_type: Option, + fiservemea_type: Option, client_request_id: Option, api_trace_id: Option, ipg_transaction_id: String, @@ -526,7 +519,7 @@ pub struct FiservemeaError { #[derive(Debug, Serialize, Deserialize)] pub struct FiservemeaErrorResponse { #[serde(rename = "type")] - fiservemea_type: Option, + fiservemea_type: Option, client_request_id: Option, api_trace_id: Option, pub response_type: Option, diff --git a/crates/hyperswitch_connectors/src/utils.rs b/crates/hyperswitch_connectors/src/utils.rs index bda133e65b70..03a4026ff61e 100644 --- a/crates/hyperswitch_connectors/src/utils.rs +++ b/crates/hyperswitch_connectors/src/utils.rs @@ -16,7 +16,11 @@ use common_utils::{ }; use error_stack::{report, ResultExt}; use hyperswitch_domain_models::{ - payment_method_data::{Card, PaymentMethodData}, + payment_method_data::{ + BankDebitData, BankRedirectData, BankTransferData, Card, CardRedirectData, GiftCardData, + OpenBankingData, PayLaterData, PaymentMethodData, RealTimePaymentData, VoucherData, + WalletData, + }, router_data::{PaymentMethodToken, RecurringMandatePaymentData}, router_request_types::{ AuthenticationData, BrowserInformation, CompleteAuthorizeData, PaymentsAuthorizeData, @@ -1357,6 +1361,271 @@ impl PaymentsCompleteAuthorizeRequestData for CompleteAuthorizeData { } } +pub fn is_mandate_supported( + selected_pmd: PaymentMethodData, + payment_method_type: Option, + mandate_implemented_pmds: std::collections::HashSet, + connector: &'static str, +) -> Result<(), Error> { + if mandate_implemented_pmds.contains(&PaymentMethodDataType::from(selected_pmd.clone())) { + Ok(()) + } else { + match payment_method_type { + Some(pm_type) => Err(errors::ConnectorError::NotSupported { + message: format!("{} mandate payment", pm_type), + connector, + } + .into()), + None => Err(errors::ConnectorError::NotSupported { + message: " mandate payment".to_string(), + connector, + } + .into()), + } + } +} + +#[derive(Debug, strum::Display, Eq, PartialEq, Hash)] +pub enum PaymentMethodDataType { + Card, + Knet, + Benefit, + MomoAtm, + CardRedirect, + AliPayQr, + AliPayRedirect, + AliPayHkRedirect, + MomoRedirect, + KakaoPayRedirect, + GoPayRedirect, + GcashRedirect, + ApplePay, + ApplePayRedirect, + ApplePayThirdPartySdk, + DanaRedirect, + DuitNow, + GooglePay, + GooglePayRedirect, + GooglePayThirdPartySdk, + MbWayRedirect, + MobilePayRedirect, + PaypalRedirect, + PaypalSdk, + SamsungPay, + TwintRedirect, + VippsRedirect, + TouchNGoRedirect, + WeChatPayRedirect, + WeChatPayQr, + CashappQr, + SwishQr, + KlarnaRedirect, + KlarnaSdk, + AffirmRedirect, + AfterpayClearpayRedirect, + PayBrightRedirect, + WalleyRedirect, + AlmaRedirect, + AtomeRedirect, + BancontactCard, + Bizum, + Blik, + Eps, + Giropay, + Ideal, + Interac, + LocalBankRedirect, + OnlineBankingCzechRepublic, + OnlineBankingFinland, + OnlineBankingPoland, + OnlineBankingSlovakia, + OpenBankingUk, + Przelewy24, + Sofort, + Trustly, + OnlineBankingFpx, + OnlineBankingThailand, + AchBankDebit, + SepaBankDebit, + BecsBankDebit, + BacsBankDebit, + AchBankTransfer, + SepaBankTransfer, + BacsBankTransfer, + MultibancoBankTransfer, + PermataBankTransfer, + BcaBankTransfer, + BniVaBankTransfer, + BriVaBankTransfer, + CimbVaBankTransfer, + DanamonVaBankTransfer, + MandiriVaBankTransfer, + Pix, + Pse, + Crypto, + MandatePayment, + Reward, + Upi, + Boleto, + Efecty, + PagoEfectivo, + RedCompra, + RedPagos, + Alfamart, + Indomaret, + Oxxo, + SevenEleven, + Lawson, + MiniStop, + FamilyMart, + Seicomart, + PayEasy, + Givex, + PaySafeCar, + CardToken, + LocalBankTransfer, + Mifinity, + Fps, + PromptPay, + VietQr, + OpenBanking, + NetworkToken, +} + +impl From for PaymentMethodDataType { + fn from(pm_data: PaymentMethodData) -> Self { + match pm_data { + PaymentMethodData::Card(_) => Self::Card, + PaymentMethodData::NetworkToken(_) => Self::NetworkToken, + PaymentMethodData::CardRedirect(card_redirect_data) => match card_redirect_data { + CardRedirectData::Knet {} => Self::Knet, + CardRedirectData::Benefit {} => Self::Benefit, + CardRedirectData::MomoAtm {} => Self::MomoAtm, + CardRedirectData::CardRedirect {} => Self::CardRedirect, + }, + PaymentMethodData::Wallet(wallet_data) => match wallet_data { + WalletData::AliPayQr(_) => Self::AliPayQr, + WalletData::AliPayRedirect(_) => Self::AliPayRedirect, + WalletData::AliPayHkRedirect(_) => Self::AliPayHkRedirect, + WalletData::MomoRedirect(_) => Self::MomoRedirect, + WalletData::KakaoPayRedirect(_) => Self::KakaoPayRedirect, + WalletData::GoPayRedirect(_) => Self::GoPayRedirect, + WalletData::GcashRedirect(_) => Self::GcashRedirect, + WalletData::ApplePay(_) => Self::ApplePay, + WalletData::ApplePayRedirect(_) => Self::ApplePayRedirect, + WalletData::ApplePayThirdPartySdk(_) => Self::ApplePayThirdPartySdk, + WalletData::DanaRedirect {} => Self::DanaRedirect, + WalletData::GooglePay(_) => Self::GooglePay, + WalletData::GooglePayRedirect(_) => Self::GooglePayRedirect, + WalletData::GooglePayThirdPartySdk(_) => Self::GooglePayThirdPartySdk, + WalletData::MbWayRedirect(_) => Self::MbWayRedirect, + WalletData::MobilePayRedirect(_) => Self::MobilePayRedirect, + WalletData::PaypalRedirect(_) => Self::PaypalRedirect, + WalletData::PaypalSdk(_) => Self::PaypalSdk, + WalletData::SamsungPay(_) => Self::SamsungPay, + WalletData::TwintRedirect {} => Self::TwintRedirect, + WalletData::VippsRedirect {} => Self::VippsRedirect, + WalletData::TouchNGoRedirect(_) => Self::TouchNGoRedirect, + WalletData::WeChatPayRedirect(_) => Self::WeChatPayRedirect, + WalletData::WeChatPayQr(_) => Self::WeChatPayQr, + WalletData::CashappQr(_) => Self::CashappQr, + WalletData::SwishQr(_) => Self::SwishQr, + WalletData::Mifinity(_) => Self::Mifinity, + }, + PaymentMethodData::PayLater(pay_later_data) => match pay_later_data { + PayLaterData::KlarnaRedirect { .. } => Self::KlarnaRedirect, + PayLaterData::KlarnaSdk { .. } => Self::KlarnaSdk, + PayLaterData::AffirmRedirect {} => Self::AffirmRedirect, + PayLaterData::AfterpayClearpayRedirect { .. } => Self::AfterpayClearpayRedirect, + PayLaterData::PayBrightRedirect {} => Self::PayBrightRedirect, + PayLaterData::WalleyRedirect {} => Self::WalleyRedirect, + PayLaterData::AlmaRedirect {} => Self::AlmaRedirect, + PayLaterData::AtomeRedirect {} => Self::AtomeRedirect, + }, + PaymentMethodData::BankRedirect(bank_redirect_data) => match bank_redirect_data { + BankRedirectData::BancontactCard { .. } => Self::BancontactCard, + BankRedirectData::Bizum {} => Self::Bizum, + BankRedirectData::Blik { .. } => Self::Blik, + BankRedirectData::Eps { .. } => Self::Eps, + BankRedirectData::Giropay { .. } => Self::Giropay, + BankRedirectData::Ideal { .. } => Self::Ideal, + BankRedirectData::Interac { .. } => Self::Interac, + BankRedirectData::OnlineBankingCzechRepublic { .. } => { + Self::OnlineBankingCzechRepublic + } + BankRedirectData::OnlineBankingFinland { .. } => Self::OnlineBankingFinland, + BankRedirectData::OnlineBankingPoland { .. } => Self::OnlineBankingPoland, + BankRedirectData::OnlineBankingSlovakia { .. } => Self::OnlineBankingSlovakia, + BankRedirectData::OpenBankingUk { .. } => Self::OpenBankingUk, + BankRedirectData::Przelewy24 { .. } => Self::Przelewy24, + BankRedirectData::Sofort { .. } => Self::Sofort, + BankRedirectData::Trustly { .. } => Self::Trustly, + BankRedirectData::OnlineBankingFpx { .. } => Self::OnlineBankingFpx, + BankRedirectData::OnlineBankingThailand { .. } => Self::OnlineBankingThailand, + BankRedirectData::LocalBankRedirect {} => Self::LocalBankRedirect, + }, + PaymentMethodData::BankDebit(bank_debit_data) => match bank_debit_data { + BankDebitData::AchBankDebit { .. } => Self::AchBankDebit, + BankDebitData::SepaBankDebit { .. } => Self::SepaBankDebit, + BankDebitData::BecsBankDebit { .. } => Self::BecsBankDebit, + BankDebitData::BacsBankDebit { .. } => Self::BacsBankDebit, + }, + PaymentMethodData::BankTransfer(bank_transfer_data) => match *bank_transfer_data { + BankTransferData::AchBankTransfer { .. } => Self::AchBankTransfer, + BankTransferData::SepaBankTransfer { .. } => Self::SepaBankTransfer, + BankTransferData::BacsBankTransfer { .. } => Self::BacsBankTransfer, + BankTransferData::MultibancoBankTransfer { .. } => Self::MultibancoBankTransfer, + BankTransferData::PermataBankTransfer { .. } => Self::PermataBankTransfer, + BankTransferData::BcaBankTransfer { .. } => Self::BcaBankTransfer, + BankTransferData::BniVaBankTransfer { .. } => Self::BniVaBankTransfer, + BankTransferData::BriVaBankTransfer { .. } => Self::BriVaBankTransfer, + BankTransferData::CimbVaBankTransfer { .. } => Self::CimbVaBankTransfer, + BankTransferData::DanamonVaBankTransfer { .. } => Self::DanamonVaBankTransfer, + BankTransferData::MandiriVaBankTransfer { .. } => Self::MandiriVaBankTransfer, + BankTransferData::Pix { .. } => Self::Pix, + BankTransferData::Pse {} => Self::Pse, + BankTransferData::LocalBankTransfer { .. } => Self::LocalBankTransfer, + }, + PaymentMethodData::Crypto(_) => Self::Crypto, + PaymentMethodData::MandatePayment => Self::MandatePayment, + PaymentMethodData::Reward => Self::Reward, + PaymentMethodData::Upi(_) => Self::Upi, + PaymentMethodData::Voucher(voucher_data) => match voucher_data { + VoucherData::Boleto(_) => Self::Boleto, + VoucherData::Efecty => Self::Efecty, + VoucherData::PagoEfectivo => Self::PagoEfectivo, + VoucherData::RedCompra => Self::RedCompra, + VoucherData::RedPagos => Self::RedPagos, + VoucherData::Alfamart(_) => Self::Alfamart, + VoucherData::Indomaret(_) => Self::Indomaret, + VoucherData::Oxxo => Self::Oxxo, + VoucherData::SevenEleven(_) => Self::SevenEleven, + VoucherData::Lawson(_) => Self::Lawson, + VoucherData::MiniStop(_) => Self::MiniStop, + VoucherData::FamilyMart(_) => Self::FamilyMart, + VoucherData::Seicomart(_) => Self::Seicomart, + VoucherData::PayEasy(_) => Self::PayEasy, + }, + PaymentMethodData::RealTimePayment(real_time_payment_data) => { + match *real_time_payment_data { + RealTimePaymentData::DuitNow {} => Self::DuitNow, + RealTimePaymentData::Fps {} => Self::Fps, + RealTimePaymentData::PromptPay {} => Self::PromptPay, + RealTimePaymentData::VietQr {} => Self::VietQr, + } + } + PaymentMethodData::GiftCard(gift_card_data) => match *gift_card_data { + GiftCardData::Givex(_) => Self::Givex, + GiftCardData::PaySafeCard {} => Self::PaySafeCar, + }, + PaymentMethodData::CardToken(_) => Self::CardToken, + PaymentMethodData::OpenBanking(data) => match data { + OpenBankingData::OpenBankingPIS {} => Self::OpenBanking, + }, + } + } +} + pub trait BrowserInformationData { fn get_accept_header(&self) -> Result; fn get_language(&self) -> Result; diff --git a/crates/hyperswitch_domain_models/src/router_data.rs b/crates/hyperswitch_domain_models/src/router_data.rs index df0b63833d9b..44acce1c7e30 100644 --- a/crates/hyperswitch_domain_models/src/router_data.rs +++ b/crates/hyperswitch_domain_models/src/router_data.rs @@ -242,6 +242,7 @@ pub struct RecurringMandatePaymentData { pub payment_method_type: Option, //required for making recurring payment using saved payment method through stripe pub original_payment_authorized_amount: Option, pub original_payment_authorized_currency: Option, + pub mandate_metadata: Option, } #[derive(Debug, Clone)] diff --git a/crates/hyperswitch_domain_models/src/router_response_types.rs b/crates/hyperswitch_domain_models/src/router_response_types.rs index cb682514c83b..b4a4e212b815 100644 --- a/crates/hyperswitch_domain_models/src/router_response_types.rs +++ b/crates/hyperswitch_domain_models/src/router_response_types.rs @@ -82,6 +82,7 @@ pub struct TaxCalculationResponseData { pub struct MandateReference { pub connector_mandate_id: Option, pub payment_method_id: Option, + pub mandate_metadata: Option, } #[derive(Debug, Clone)] diff --git a/crates/hyperswitch_interfaces/src/errors.rs b/crates/hyperswitch_interfaces/src/errors.rs index e36707af6b05..06f197ebf0b9 100644 --- a/crates/hyperswitch_interfaces/src/errors.rs +++ b/crates/hyperswitch_interfaces/src/errors.rs @@ -56,6 +56,8 @@ pub enum ConnectorError { CaptureMethodNotSupported, #[error("Missing connector mandate ID")] MissingConnectorMandateID, + #[error("Missing connector mandate metadata")] + MissingConnectorMandateMetadata, #[error("Missing connector transaction ID")] MissingConnectorTransactionID, #[error("Missing connector refund ID")] diff --git a/crates/router/src/connector/aci/transformers.rs b/crates/router/src/connector/aci/transformers.rs index 5842143ad445..46f312b38f26 100644 --- a/crates/router/src/connector/aci/transformers.rs +++ b/crates/router/src/connector/aci/transformers.rs @@ -746,6 +746,7 @@ impl .map(|id| types::MandateReference { connector_mandate_id: Some(id.expose()), payment_method_id: None, + mandate_metadata: None, }); Ok(Self { diff --git a/crates/router/src/connector/adyen/transformers.rs b/crates/router/src/connector/adyen/transformers.rs index 2539c5c52f97..8857c2fdce0d 100644 --- a/crates/router/src/connector/adyen/transformers.rs +++ b/crates/router/src/connector/adyen/transformers.rs @@ -3288,6 +3288,7 @@ pub fn get_adyen_response( .map(|mandate_id| types::MandateReference { connector_mandate_id: Some(mandate_id.expose()), payment_method_id: None, + mandate_metadata: None, }); let network_txn_id = response.additional_data.and_then(|additional_data| { additional_data diff --git a/crates/router/src/connector/authorizedotnet/transformers.rs b/crates/router/src/connector/authorizedotnet/transformers.rs index e04fe3e3fba9..680926b8a834 100644 --- a/crates/router/src/connector/authorizedotnet/transformers.rs +++ b/crates/router/src/connector/authorizedotnet/transformers.rs @@ -398,6 +398,7 @@ impl format!("{customer_profile_id}-{payment_profile_id}") }), payment_method_id: None, + mandate_metadata: None, }, ), connector_metadata: None, @@ -1104,6 +1105,7 @@ impl }, ), payment_method_id: None, + mandate_metadata: None, } }); diff --git a/crates/router/src/connector/bamboraapac/transformers.rs b/crates/router/src/connector/bamboraapac/transformers.rs index 3c1976993099..819c918338e7 100644 --- a/crates/router/src/connector/bamboraapac/transformers.rs +++ b/crates/router/src/connector/bamboraapac/transformers.rs @@ -280,6 +280,7 @@ impl Some(types::MandateReference { connector_mandate_id, payment_method_id: None, + mandate_metadata: None, }) } else { None @@ -463,6 +464,7 @@ impl mandate_reference: Some(types::MandateReference { connector_mandate_id: Some(connector_mandate_id), payment_method_id: None, + mandate_metadata: None, }), connector_metadata: None, network_txn_id: None, diff --git a/crates/router/src/connector/bankofamerica/transformers.rs b/crates/router/src/connector/bankofamerica/transformers.rs index 46a522c73782..f47ab4139e8b 100644 --- a/crates/router/src/connector/bankofamerica/transformers.rs +++ b/crates/router/src/connector/bankofamerica/transformers.rs @@ -359,6 +359,7 @@ impl .payment_instrument .map(|payment_instrument| payment_instrument.id.expose()), payment_method_id: None, + mandate_metadata: None, } }); let mut mandate_status = @@ -1487,6 +1488,7 @@ fn get_payment_response( .payment_instrument .map(|payment_instrument| payment_instrument.id.expose()), payment_method_id: None, + mandate_metadata: None, }); Ok(types::PaymentsResponseData::TransactionResponse { diff --git a/crates/router/src/connector/braintree/transformers.rs b/crates/router/src/connector/braintree/transformers.rs index 22982ceb2132..05d8c1c559d6 100644 --- a/crates/router/src/connector/braintree/transformers.rs +++ b/crates/router/src/connector/braintree/transformers.rs @@ -443,6 +443,7 @@ impl MandateReference { connector_mandate_id: Some(pm.id.clone().expose()), payment_method_id: None, + mandate_metadata: None, } }), connector_metadata: None, @@ -617,6 +618,7 @@ impl MandateReference { connector_mandate_id: Some(pm.id.clone().expose()), payment_method_id: None, + mandate_metadata: None, } }), connector_metadata: None, @@ -698,6 +700,7 @@ impl MandateReference { connector_mandate_id: Some(pm.id.clone().expose()), payment_method_id: None, + mandate_metadata: None, } }), connector_metadata: None, @@ -761,6 +764,7 @@ impl MandateReference { connector_mandate_id: Some(pm.id.clone().expose()), payment_method_id: None, + mandate_metadata: None, } }), connector_metadata: None, diff --git a/crates/router/src/connector/cybersource/transformers.rs b/crates/router/src/connector/cybersource/transformers.rs index 6af3c6006577..0bd529b1b1f3 100644 --- a/crates/router/src/connector/cybersource/transformers.rs +++ b/crates/router/src/connector/cybersource/transformers.rs @@ -2056,6 +2056,7 @@ fn get_payment_response( .payment_instrument .map(|payment_instrument| payment_instrument.id.expose()), payment_method_id: None, + mandate_metadata: None, }); Ok(types::PaymentsResponseData::TransactionResponse { @@ -2776,6 +2777,7 @@ impl .payment_instrument .map(|payment_instrument| payment_instrument.id.expose()), payment_method_id: None, + mandate_metadata: None, }); let mut mandate_status = enums::AttemptStatus::foreign_from(( item.response diff --git a/crates/router/src/connector/globalpay/transformers.rs b/crates/router/src/connector/globalpay/transformers.rs index efc6661b447b..19568ae4671f 100644 --- a/crates/router/src/connector/globalpay/transformers.rs +++ b/crates/router/src/connector/globalpay/transformers.rs @@ -261,6 +261,7 @@ fn get_payment_response( .map(|id| types::MandateReference { connector_mandate_id: Some(id.expose()), payment_method_id: None, + mandate_metadata: None, }) }); match status { diff --git a/crates/router/src/connector/gocardless/transformers.rs b/crates/router/src/connector/gocardless/transformers.rs index f3250602dbcf..ff2f9d95026e 100644 --- a/crates/router/src/connector/gocardless/transformers.rs +++ b/crates/router/src/connector/gocardless/transformers.rs @@ -512,6 +512,7 @@ impl let mandate_reference = Some(MandateReference { connector_mandate_id: Some(item.response.mandates.id.clone().expose()), payment_method_id: None, + mandate_metadata: None, }); Ok(Self { response: Ok(types::PaymentsResponseData::TransactionResponse { @@ -664,6 +665,7 @@ impl let mandate_reference = MandateReference { connector_mandate_id: Some(item.data.request.get_connector_mandate_id()?), payment_method_id: None, + mandate_metadata: None, }; Ok(Self { status: enums::AttemptStatus::from(item.response.payments.status), diff --git a/crates/router/src/connector/multisafepay/transformers.rs b/crates/router/src/connector/multisafepay/transformers.rs index c44cf14ab65c..547a38ad8498 100644 --- a/crates/router/src/connector/multisafepay/transformers.rs +++ b/crates/router/src/connector/multisafepay/transformers.rs @@ -982,6 +982,7 @@ impl .map(|id| types::MandateReference { connector_mandate_id: Some(id.expose()), payment_method_id: None, + mandate_metadata: None, }), connector_metadata: None, network_txn_id: None, diff --git a/crates/router/src/connector/nexinets/transformers.rs b/crates/router/src/connector/nexinets/transformers.rs index 43cb4cecec8d..55b2fbe41763 100644 --- a/crates/router/src/connector/nexinets/transformers.rs +++ b/crates/router/src/connector/nexinets/transformers.rs @@ -358,6 +358,7 @@ impl .map(|id| types::MandateReference { connector_mandate_id: Some(id.expose()), payment_method_id: None, + mandate_metadata: None, }); Ok(Self { status: enums::AttemptStatus::foreign_from(( diff --git a/crates/router/src/connector/noon/transformers.rs b/crates/router/src/connector/noon/transformers.rs index b7df6829da47..5d9871742730 100644 --- a/crates/router/src/connector/noon/transformers.rs +++ b/crates/router/src/connector/noon/transformers.rs @@ -574,6 +574,7 @@ impl .map(|subscription_data| types::MandateReference { connector_mandate_id: Some(subscription_data.identifier.expose()), payment_method_id: None, + mandate_metadata: None, }); Ok(Self { status, diff --git a/crates/router/src/connector/nuvei/transformers.rs b/crates/router/src/connector/nuvei/transformers.rs index 2547443484e6..f280d3a42a2a 100644 --- a/crates/router/src/connector/nuvei/transformers.rs +++ b/crates/router/src/connector/nuvei/transformers.rs @@ -1602,6 +1602,7 @@ where .map(|id| types::MandateReference { connector_mandate_id: Some(id), payment_method_id: None, + mandate_metadata: None, }), // we don't need to save session token for capture, void flow so ignoring if it is not present connector_metadata: if let Some(token) = response.session_token { diff --git a/crates/router/src/connector/payeezy/transformers.rs b/crates/router/src/connector/payeezy/transformers.rs index 0bb10c9845a3..8c2ad2ef9799 100644 --- a/crates/router/src/connector/payeezy/transformers.rs +++ b/crates/router/src/connector/payeezy/transformers.rs @@ -418,6 +418,7 @@ impl .map(|id| types::MandateReference { connector_mandate_id: Some(id.expose()), payment_method_id: None, + mandate_metadata: None, }); let status = enums::AttemptStatus::foreign_from(( item.response.transaction_status, diff --git a/crates/router/src/connector/payme/transformers.rs b/crates/router/src/connector/payme/transformers.rs index c12e478b08e5..e0ab598d76d6 100644 --- a/crates/router/src/connector/payme/transformers.rs +++ b/crates/router/src/connector/payme/transformers.rs @@ -250,6 +250,7 @@ impl TryFrom<&PaymePaySaleResponse> for types::PaymentsResponseData { mandate_reference: value.buyer_key.clone().map(|buyer_key| MandateReference { connector_mandate_id: Some(buyer_key.expose()), payment_method_id: None, + mandate_metadata: None, }), connector_metadata: None, network_txn_id: None, diff --git a/crates/router/src/connector/stripe/transformers.rs b/crates/router/src/connector/stripe/transformers.rs index 167219940745..f1ee0ad5ba09 100644 --- a/crates/router/src/connector/stripe/transformers.rs +++ b/crates/router/src/connector/stripe/transformers.rs @@ -2383,6 +2383,7 @@ impl types::MandateReference { connector_mandate_id, payment_method_id, + mandate_metadata: None, } }); @@ -2577,6 +2578,7 @@ impl types::MandateReference { connector_mandate_id, payment_method_id: Some(payment_method_id), + mandate_metadata: None, } }); @@ -2667,6 +2669,7 @@ impl types::MandateReference { connector_mandate_id, payment_method_id, + mandate_metadata: None, } }); let status = enums::AttemptStatus::from(item.response.status); diff --git a/crates/router/src/connector/wellsfargo/transformers.rs b/crates/router/src/connector/wellsfargo/transformers.rs index d368504a5fc6..b9a9d003ec06 100644 --- a/crates/router/src/connector/wellsfargo/transformers.rs +++ b/crates/router/src/connector/wellsfargo/transformers.rs @@ -1776,6 +1776,7 @@ fn get_payment_response( .payment_instrument .map(|payment_instrument| payment_instrument.id.expose()), payment_method_id: None, + mandate_metadata: None, }); Ok(types::PaymentsResponseData::TransactionResponse { @@ -1961,6 +1962,7 @@ impl .payment_instrument .map(|payment_instrument| payment_instrument.id.expose()), payment_method_id: None, + mandate_metadata: None, }); let mut mandate_status = enums::AttemptStatus::foreign_from(( item.response diff --git a/crates/router/src/core/errors/utils.rs b/crates/router/src/core/errors/utils.rs index d2812447ed89..549857494f02 100644 --- a/crates/router/src/core/errors/utils.rs +++ b/crates/router/src/core/errors/utils.rs @@ -189,6 +189,7 @@ impl ConnectorErrorExt for error_stack::Result | errors::ConnectorError::FlowNotSupported { .. } | errors::ConnectorError::CaptureMethodNotSupported | errors::ConnectorError::MissingConnectorMandateID + | errors::ConnectorError::MissingConnectorMandateMetadata | errors::ConnectorError::MissingConnectorTransactionID | errors::ConnectorError::MissingConnectorRefundID | errors::ConnectorError::MissingApplePayTokenData @@ -288,6 +289,7 @@ impl ConnectorErrorExt for error_stack::Result errors::ConnectorError::FailedToObtainCertificateKey | errors::ConnectorError::CaptureMethodNotSupported | errors::ConnectorError::MissingConnectorMandateID | + errors::ConnectorError::MissingConnectorMandateMetadata | errors::ConnectorError::MissingConnectorTransactionID | errors::ConnectorError::MissingConnectorRefundID | errors::ConnectorError::MissingApplePayTokenData | @@ -376,6 +378,7 @@ impl ConnectorErrorExt for error_stack::Result | errors::ConnectorError::FlowNotSupported { .. } | errors::ConnectorError::CaptureMethodNotSupported | errors::ConnectorError::MissingConnectorMandateID + | errors::ConnectorError::MissingConnectorMandateMetadata | errors::ConnectorError::MissingConnectorTransactionID | errors::ConnectorError::MissingConnectorRefundID | errors::ConnectorError::MissingApplePayTokenData diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs index 3ff5e649f20b..026bea8de528 100644 --- a/crates/router/src/core/payments.rs +++ b/crates/router/src/core/payments.rs @@ -3920,6 +3920,9 @@ where payment_method_info.get_id().clone(), ), update_history: None, + mandate_metadata: mandate_reference_record + .mandate_metadata + .clone(), }, )); payment_data.set_recurring_mandate_payment_data( @@ -3930,6 +3933,8 @@ where .original_payment_authorized_amount, original_payment_authorized_currency: mandate_reference_record .original_payment_authorized_currency, + mandate_metadata: mandate_reference_record + .mandate_metadata.clone(), }); connector_choice = Some((connector_data, mandate_reference_id.clone())); @@ -3956,7 +3961,7 @@ where mandate_id: None, mandate_reference_id, }); - + // payment_data. Ok(ConnectorCallType::PreDetermined(chosen_connector_data)) } ( diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index 6cb4532d6179..0bd161a7c577 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -802,6 +802,7 @@ pub async fn get_token_for_recurring_mandate( payment_method_type, original_payment_authorized_amount, original_payment_authorized_currency, + mandate_metadata: None, // }), payment_method_type: payment_method.payment_method_type, mandate_connector: Some(mandate_connector_details), @@ -816,6 +817,7 @@ pub async fn get_token_for_recurring_mandate( payment_method_type, original_payment_authorized_amount, original_payment_authorized_currency, + mandate_metadata: None, // }), payment_method_type: payment_method.payment_method_type, mandate_connector: Some(mandate_connector_details), diff --git a/crates/router/src/core/payments/operations/payment_confirm.rs b/crates/router/src/core/payments/operations/payment_confirm.rs index 90158793f960..6717c05c632f 100644 --- a/crates/router/src/core/payments/operations/payment_confirm.rs +++ b/crates/router/src/core/payments/operations/payment_confirm.rs @@ -681,6 +681,7 @@ impl GetTracker, api::PaymentsRequest> for Pa ), payment_method_id: None, update_history: None, + mandate_metadata: None, }, ), ), diff --git a/crates/router/src/core/payments/operations/payment_create.rs b/crates/router/src/core/payments/operations/payment_create.rs index d66565e84e58..3748b3757e37 100644 --- a/crates/router/src/core/payments/operations/payment_create.rs +++ b/crates/router/src/core/payments/operations/payment_create.rs @@ -386,7 +386,8 @@ impl GetTracker, api::PaymentsRequest> for Pa api_models::payments::ConnectorMandateReferenceId{ connector_mandate_id: connector_id.connector_mandate_id, payment_method_id: connector_id.payment_method_id, - update_history: None + update_history: None, + mandate_metadata: None, } )) } @@ -425,6 +426,7 @@ impl GetTracker, api::PaymentsRequest> for Pa ), payment_method_id: None, update_history: None, + mandate_metadata: None, }, ), ), diff --git a/crates/router/src/core/payments/operations/payment_response.rs b/crates/router/src/core/payments/operations/payment_response.rs index 5471ae355f5c..f22b97d2b1c6 100644 --- a/crates/router/src/core/payments/operations/payment_response.rs +++ b/crates/router/src/core/payments/operations/payment_response.rs @@ -1422,21 +1422,24 @@ async fn payment_response_update_tracker( let flow_name = core_utils::get_flow_name::()?; if flow_name == "PSync" || flow_name == "CompleteAuthorize" { - let connector_mandate_id = match router_data.response.clone() { + let (connector_mandate_id, mandate_metdata) = match router_data.response.clone() { Ok(resp) => match resp { types::PaymentsResponseData::TransactionResponse { ref mandate_reference, .. } => { if let Some(mandate_ref) = mandate_reference { - mandate_ref.connector_mandate_id.clone() + ( + mandate_ref.connector_mandate_id.clone(), + mandate_ref.mandate_metadata.clone(), + ) } else { - None + (None, None) } } - _ => None, + _ => (None, None), }, - Err(_) => None, + Err(_) => (None, None), }; if let Some(payment_method) = payment_data.payment_method_info.clone() { let connector_mandate_details = @@ -1447,6 +1450,7 @@ async fn payment_response_update_tracker( payment_data.payment_attempt.currency, payment_data.payment_attempt.merchant_connector_id.clone(), connector_mandate_id, + mandate_metdata, )?; payment_methods::cards::update_payment_method_connector_mandate_details( state, diff --git a/crates/router/src/core/payments/operations/payment_update.rs b/crates/router/src/core/payments/operations/payment_update.rs index 484bec14f484..5ef892b44ca2 100644 --- a/crates/router/src/core/payments/operations/payment_update.rs +++ b/crates/router/src/core/payments/operations/payment_update.rs @@ -329,7 +329,7 @@ impl GetTracker, api::PaymentsRequest> for Pa api_models::payments::MandateIds { mandate_id: Some(mandate_obj.mandate_id), mandate_reference_id: Some(api_models::payments::MandateReferenceId::ConnectorMandateId( - api_models::payments::ConnectorMandateReferenceId {connector_mandate_id:connector_id.connector_mandate_id,payment_method_id:connector_id.payment_method_id, update_history: None }, + api_models::payments::ConnectorMandateReferenceId {connector_mandate_id:connector_id.connector_mandate_id,payment_method_id:connector_id.payment_method_id, update_history: None, mandate_metadata:connector_id.mandate_metadata, }, )) } }), diff --git a/crates/router/src/core/payments/tokenization.rs b/crates/router/src/core/payments/tokenization.rs index 609d5592ffd5..58f09150785c 100644 --- a/crates/router/src/core/payments/tokenization.rs +++ b/crates/router/src/core/payments/tokenization.rs @@ -148,18 +148,21 @@ where .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Unable to serialize customer acceptance to value")?; - let connector_mandate_id = match responses { + let (connector_mandate_id, mandate_metdata) = match responses { types::PaymentsResponseData::TransactionResponse { ref mandate_reference, .. } => { if let Some(mandate_ref) = mandate_reference { - mandate_ref.connector_mandate_id.clone() + ( + mandate_ref.connector_mandate_id.clone(), + mandate_ref.mandate_metadata.clone(), + ) } else { - None + (None, None) } } - _ => None, + _ => (None, None), }; let check_for_mit_mandates = save_payment_method_data .request @@ -178,6 +181,7 @@ where currency, merchant_connector_id.clone(), connector_mandate_id.clone(), + mandate_metdata.clone(), ) } else { None @@ -312,6 +316,7 @@ where currency, merchant_connector_id.clone(), connector_mandate_id.clone(), + mandate_metdata.clone(), )?; payment_methods::cards::update_payment_method_connector_mandate_details(state, @@ -415,6 +420,7 @@ where currency, merchant_connector_id.clone(), connector_mandate_id.clone(), + mandate_metdata.clone(), )?; payment_methods::cards::update_payment_method_connector_mandate_details( state, @@ -1002,6 +1008,7 @@ pub fn add_connector_mandate_details_in_payment_method( authorized_currency: Option, merchant_connector_id: Option, connector_mandate_id: Option, + mandate_metadata: Option, ) -> Option { let mut mandate_details = HashMap::new(); @@ -1015,6 +1022,7 @@ pub fn add_connector_mandate_details_in_payment_method( payment_method_type, original_payment_authorized_amount: authorized_amount, original_payment_authorized_currency: authorized_currency, + mandate_metadata, }, ); Some(storage::PaymentsMandateReference(mandate_details)) @@ -1030,6 +1038,7 @@ pub fn update_connector_mandate_details_in_payment_method( authorized_currency: Option, merchant_connector_id: Option, connector_mandate_id: Option, + mandate_metadata: Option, ) -> RouterResult> { let mandate_reference = match payment_method.connector_mandate_details { Some(_) => { @@ -1050,6 +1059,7 @@ pub fn update_connector_mandate_details_in_payment_method( payment_method_type, original_payment_authorized_amount: authorized_amount, original_payment_authorized_currency: authorized_currency, + mandate_metadata: mandate_metadata.clone(), }; mandate_details.map(|mut payment_mandate_reference| { payment_mandate_reference @@ -1060,6 +1070,7 @@ pub fn update_connector_mandate_details_in_payment_method( payment_method_type, original_payment_authorized_amount: authorized_amount, original_payment_authorized_currency: authorized_currency, + mandate_metadata: mandate_metadata.clone(), }); payment_mandate_reference }) @@ -1073,6 +1084,7 @@ pub fn update_connector_mandate_details_in_payment_method( authorized_currency, merchant_connector_id, connector_mandate_id, + mandate_metadata, ), }; let connector_mandate_details = mandate_reference diff --git a/crates/router/src/types/storage/payment_method.rs b/crates/router/src/types/storage/payment_method.rs index 0e7bdb14d4a0..6941c864aad4 100644 --- a/crates/router/src/types/storage/payment_method.rs +++ b/crates/router/src/types/storage/payment_method.rs @@ -92,6 +92,7 @@ pub struct PaymentsMandateReferenceRecord { pub payment_method_type: Option, pub original_payment_authorized_amount: Option, pub original_payment_authorized_currency: Option, + pub mandate_metadata: Option, } #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] From e9d6e7ffc6a1125d2849bf3e22d4291f48983b9f Mon Sep 17 00:00:00 2001 From: deepanshu-iiitu Date: Tue, 17 Sep 2024 17:16:14 +0530 Subject: [PATCH 02/11] chore: Fix merge conflicts --- .../src/connectors/deutschebank/transformers.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs b/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs index 11517de7409d..15302d4c3ce6 100644 --- a/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs @@ -188,7 +188,8 @@ impl TryFrom<&DeutschebankRouterData<&PaymentsAuthorizeRouterData>> }, })) } - Some(api_models::payments::MandateReferenceId::NetworkMandateId(_)) => { + Some(MandateReferenceId::NetworkTokenWithNTI(_)) + | Some(api_models::payments::MandateReferenceId::NetworkMandateId(_)) => { Err(errors::ConnectorError::NotImplemented( utils::get_unimplemented_payment_method_error_message("deutschebank"), ) From ced09c52e1da0e67fd400c7f54ead4d56f3e52bb Mon Sep 17 00:00:00 2001 From: deepanshu-iiitu Date: Tue, 17 Sep 2024 17:17:22 +0530 Subject: [PATCH 03/11] chore: Fix merge conflicts --- .../src/connectors/deutschebank/transformers.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs b/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs index 15302d4c3ce6..752c8645ef64 100644 --- a/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs @@ -188,7 +188,7 @@ impl TryFrom<&DeutschebankRouterData<&PaymentsAuthorizeRouterData>> }, })) } - Some(MandateReferenceId::NetworkTokenWithNTI(_)) + Some(api_models::payments::MandateReferenceId::NetworkTokenWithNTI(_)) | Some(api_models::payments::MandateReferenceId::NetworkMandateId(_)) => { Err(errors::ConnectorError::NotImplemented( utils::get_unimplemented_payment_method_error_message("deutschebank"), From 8ff42ff7917db5183ae17fa0661b3746bd62b147 Mon Sep 17 00:00:00 2001 From: deepanshu-iiitu Date: Tue, 17 Sep 2024 17:24:00 +0530 Subject: [PATCH 04/11] chore: Fix Spelling errors --- .../src/core/payments/operations/payment_response.rs | 4 ++-- crates/router/src/core/payments/tokenization.rs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/router/src/core/payments/operations/payment_response.rs b/crates/router/src/core/payments/operations/payment_response.rs index 9bc41a91cbf2..3acef8d2adff 100644 --- a/crates/router/src/core/payments/operations/payment_response.rs +++ b/crates/router/src/core/payments/operations/payment_response.rs @@ -1484,7 +1484,7 @@ async fn payment_response_update_tracker( let flow_name = core_utils::get_flow_name::()?; if flow_name == "PSync" || flow_name == "CompleteAuthorize" { - let (connector_mandate_id, mandate_metdata) = match router_data.response.clone() { + let (connector_mandate_id, mandate_metadata) = match router_data.response.clone() { Ok(resp) => match resp { types::PaymentsResponseData::TransactionResponse { ref mandate_reference, @@ -1512,7 +1512,7 @@ async fn payment_response_update_tracker( payment_data.payment_attempt.currency, payment_data.payment_attempt.merchant_connector_id.clone(), connector_mandate_id, - mandate_metdata, + mandate_metadata, )?; payment_methods::cards::update_payment_method_connector_mandate_details( state, diff --git a/crates/router/src/core/payments/tokenization.rs b/crates/router/src/core/payments/tokenization.rs index 84d8a9d1c83b..7f1253007752 100644 --- a/crates/router/src/core/payments/tokenization.rs +++ b/crates/router/src/core/payments/tokenization.rs @@ -148,7 +148,7 @@ where .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Unable to serialize customer acceptance to value")?; - let (connector_mandate_id, mandate_metdata) = match responses { + let (connector_mandate_id, mandate_metadata) = match responses { types::PaymentsResponseData::TransactionResponse { ref mandate_reference, .. @@ -181,7 +181,7 @@ where currency, merchant_connector_id.clone(), connector_mandate_id.clone(), - mandate_metdata.clone(), + mandate_metadata.clone(), ) } else { None @@ -377,7 +377,7 @@ where currency, merchant_connector_id.clone(), connector_mandate_id.clone(), - mandate_metdata.clone(), + mandate_metadata.clone(), )?; payment_methods::cards::update_payment_method_connector_mandate_details(state, @@ -484,7 +484,7 @@ where currency, merchant_connector_id.clone(), connector_mandate_id.clone(), - mandate_metdata.clone(), + mandate_metadata.clone(), )?; payment_methods::cards::update_payment_method_connector_mandate_details( state, From 7c5e67985b264968e5fa6ecc60c31fc2e873db28 Mon Sep 17 00:00:00 2001 From: deepanshu-iiitu Date: Tue, 17 Sep 2024 18:56:50 +0530 Subject: [PATCH 05/11] feat(connector): [DEUTSCHE] Handle authorize response --- .../src/connectors/deutschebank.rs | 36 +++++++++++----- .../connectors/deutschebank/transformers.rs | 43 +++++++++++++++++++ 2 files changed, 68 insertions(+), 11 deletions(-) diff --git a/crates/hyperswitch_connectors/src/connectors/deutschebank.rs b/crates/hyperswitch_connectors/src/connectors/deutschebank.rs index 5f38e3e830fc..a861155afb3a 100644 --- a/crates/hyperswitch_connectors/src/connectors/deutschebank.rs +++ b/crates/hyperswitch_connectors/src/connectors/deutschebank.rs @@ -382,17 +382,31 @@ impl ConnectorIntegration, res: Response, ) -> CustomResult { - let response: deutschebank::DeutschebankMandatePostResponse = res - .response - .parse_struct("Deutschebank PaymentsAuthorizeResponse") - .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, - }) + if data.request.connector_mandate_id().is_none() { + let response: deutschebank::DeutschebankMandatePostResponse = res + .response + .parse_struct("DeutschebankMandatePostResponse") + .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 { + let response: deutschebank::DeutschebankPaymentsResponse = 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, + }) + } } fn get_error_response( diff --git a/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs b/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs index 752c8645ef64..7ebd36ba2e6d 100644 --- a/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs @@ -333,6 +333,49 @@ impl } } +impl + TryFrom< + ResponseRouterData< + Authorize, + DeutschebankPaymentsResponse, + PaymentsAuthorizeData, + PaymentsResponseData, + >, + > for RouterData +{ + type Error = error_stack::Report; + fn try_from( + item: ResponseRouterData< + Authorize, + DeutschebankPaymentsResponse, + PaymentsAuthorizeData, + PaymentsResponseData, + >, + ) -> Result { + Ok(Self { + status: if item.response.rc == "0" { + match item.data.request.is_auto_capture()? { + true => common_enums::AttemptStatus::Charged, + false => common_enums::AttemptStatus::Authorized, + } + } else { + common_enums::AttemptStatus::Failure + }, + response: Ok(PaymentsResponseData::TransactionResponse { + resource_id: ResponseId::ConnectorTransactionId(item.response.tx_id), + redirection_data: None, + mandate_reference: None, + connector_metadata: None, + network_txn_id: None, + connector_response_reference_id: None, + incremental_authorization_allowed: None, + charge_id: None, + }), + ..item.data + }) + } +} + #[derive(Debug, Serialize, Deserialize, PartialEq)] pub struct DeutschebankAmount { amount: MinorUnit, From 85f0c5ba6c971b26c5a3343e24f3ab201fee9fae Mon Sep 17 00:00:00 2001 From: deepanshu-iiitu Date: Thu, 19 Sep 2024 14:15:18 +0530 Subject: [PATCH 06/11] chore: Resolve PR Comments --- crates/api_models/src/payments.rs | 2 +- .../connectors/deutschebank/transformers.rs | 33 +++++++++---------- .../src/router_data.rs | 2 +- .../src/router_response_types.rs | 2 +- crates/router/src/core/payments/helpers.rs | 4 +-- .../router/src/core/payments/tokenization.rs | 4 +-- .../src/types/storage/payment_method.rs | 2 +- 7 files changed, 23 insertions(+), 26 deletions(-) diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index 8fe46f9b1b5b..66d0ab82dd9d 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -1042,7 +1042,7 @@ pub struct ConnectorMandateReferenceId { pub connector_mandate_id: Option, pub payment_method_id: Option, pub update_history: Option>, - pub mandate_metadata: Option, + pub mandate_metadata: Option, } #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Eq, PartialEq)] diff --git a/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs b/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs index 7ebd36ba2e6d..9e8524656624 100644 --- a/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs @@ -167,7 +167,6 @@ impl TryFrom<&DeutschebankRouterData<&PaymentsAuthorizeRouterData>> let mandate_metadata: DeutschebankMandateMetadata = mandate_data .mandate_metadata .ok_or(errors::ConnectorError::MissingConnectorMandateMetadata)? - .peek() .clone() .parse_value("DeutschebankMandateMetadata") .change_context(errors::ConnectorError::ParsingFailed)?; @@ -299,23 +298,21 @@ impl mandate_reference: Some(MandateReference { connector_mandate_id: item.response.mandate_id, payment_method_id: None, - mandate_metadata: Some( - serde_json::json!(DeutschebankMandateMetadata { - account_holder: item.data.get_billing_address()?.get_full_name()?, - iban: match item.data.request.payment_method_data.clone() { - PaymentMethodData::BankDebit( - BankDebitData::SepaBankDebit { iban, .. }, - ) => Ok(iban), - _ => Err(errors::ConnectorError::MissingRequiredField { - field_name: - "payment_method_data.bank_debit.sepa_bank_debit.iban" - }), - }?, - reference: Secret::from(reference), - signed_on, - }) - .into(), - ), + mandate_metadata: Some(serde_json::json!(DeutschebankMandateMetadata { + account_holder: item.data.get_billing_address()?.get_full_name()?, + iban: match item.data.request.payment_method_data.clone() { + PaymentMethodData::BankDebit(BankDebitData::SepaBankDebit { + iban, + .. + }) => Ok(iban), + _ => Err(errors::ConnectorError::MissingRequiredField { + field_name: + "payment_method_data.bank_debit.sepa_bank_debit.iban" + }), + }?, + reference: Secret::from(reference), + signed_on, + })), }), connector_metadata: None, network_txn_id: None, diff --git a/crates/hyperswitch_domain_models/src/router_data.rs b/crates/hyperswitch_domain_models/src/router_data.rs index 44acce1c7e30..a9451f6156a2 100644 --- a/crates/hyperswitch_domain_models/src/router_data.rs +++ b/crates/hyperswitch_domain_models/src/router_data.rs @@ -242,7 +242,7 @@ pub struct RecurringMandatePaymentData { pub payment_method_type: Option, //required for making recurring payment using saved payment method through stripe pub original_payment_authorized_amount: Option, pub original_payment_authorized_currency: Option, - pub mandate_metadata: Option, + pub mandate_metadata: Option, } #[derive(Debug, Clone)] diff --git a/crates/hyperswitch_domain_models/src/router_response_types.rs b/crates/hyperswitch_domain_models/src/router_response_types.rs index b4a4e212b815..79a78efb5383 100644 --- a/crates/hyperswitch_domain_models/src/router_response_types.rs +++ b/crates/hyperswitch_domain_models/src/router_response_types.rs @@ -82,7 +82,7 @@ pub struct TaxCalculationResponseData { pub struct MandateReference { pub connector_mandate_id: Option, pub payment_method_id: Option, - pub mandate_metadata: Option, + pub mandate_metadata: Option, } #[derive(Debug, Clone)] diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index ddc93d0b2f3e..2dab94095cee 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -802,7 +802,7 @@ pub async fn get_token_for_recurring_mandate( payment_method_type, original_payment_authorized_amount, original_payment_authorized_currency, - mandate_metadata: None, // + mandate_metadata: None, }), payment_method_type: payment_method.payment_method_type, mandate_connector: Some(mandate_connector_details), @@ -817,7 +817,7 @@ pub async fn get_token_for_recurring_mandate( payment_method_type, original_payment_authorized_amount, original_payment_authorized_currency, - mandate_metadata: None, // + mandate_metadata: None, }), payment_method_type: payment_method.payment_method_type, mandate_connector: Some(mandate_connector_details), diff --git a/crates/router/src/core/payments/tokenization.rs b/crates/router/src/core/payments/tokenization.rs index 7f1253007752..03c49b0d7161 100644 --- a/crates/router/src/core/payments/tokenization.rs +++ b/crates/router/src/core/payments/tokenization.rs @@ -1166,7 +1166,7 @@ pub fn add_connector_mandate_details_in_payment_method( authorized_currency: Option, merchant_connector_id: Option, connector_mandate_id: Option, - mandate_metadata: Option, + mandate_metadata: Option, ) -> Option { let mut mandate_details = HashMap::new(); @@ -1196,7 +1196,7 @@ pub fn update_connector_mandate_details_in_payment_method( authorized_currency: Option, merchant_connector_id: Option, connector_mandate_id: Option, - mandate_metadata: Option, + mandate_metadata: Option, ) -> RouterResult> { let mandate_reference = match payment_method.connector_mandate_details { Some(_) => { diff --git a/crates/router/src/types/storage/payment_method.rs b/crates/router/src/types/storage/payment_method.rs index 47f7209d382f..fac51cf0c63c 100644 --- a/crates/router/src/types/storage/payment_method.rs +++ b/crates/router/src/types/storage/payment_method.rs @@ -95,7 +95,7 @@ pub struct PaymentsMandateReferenceRecord { pub payment_method_type: Option, pub original_payment_authorized_amount: Option, pub original_payment_authorized_currency: Option, - pub mandate_metadata: Option, + pub mandate_metadata: Option, } #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] From f30f23ca7ed18d4e57e121547d4a2bd001e7e0ce Mon Sep 17 00:00:00 2001 From: deepanshu-iiitu Date: Thu, 19 Sep 2024 16:45:40 +0530 Subject: [PATCH 07/11] chore: Resolve PR Comments --- .../connectors/deutschebank/transformers.rs | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs b/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs index 9e8524656624..8b3837edd630 100644 --- a/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs @@ -146,21 +146,30 @@ impl TryFrom<&DeutschebankRouterData<&PaymentsAuthorizeRouterData>> .and_then(|mandate_id| mandate_id.mandate_reference_id) { None => { - let billing_address = item.router_data.get_billing_address()?; - match item.router_data.request.payment_method_data.clone() { - PaymentMethodData::BankDebit(BankDebitData::SepaBankDebit { iban, .. }) => { - Ok(Self::MandatePost(DeutschebankMandatePostRequest { - approval_by: DeutschebankSEPAApproval::Click, - email_address: item.router_data.request.get_email()?, - iban, - first_name: billing_address.get_first_name()?.clone(), - last_name: billing_address.get_last_name()?.clone(), - })) + if item.router_data.request.is_mandate_payment() { + match item.router_data.request.payment_method_data.clone() { + PaymentMethodData::BankDebit(BankDebitData::SepaBankDebit { + iban, .. + }) => { + let billing_address = item.router_data.get_billing_address()?; + Ok(Self::MandatePost(DeutschebankMandatePostRequest { + approval_by: DeutschebankSEPAApproval::Click, + email_address: item.router_data.request.get_email()?, + iban, + first_name: billing_address.get_first_name()?.clone(), + last_name: billing_address.get_last_name()?.clone(), + })) + } + _ => Err(errors::ConnectorError::NotImplemented( + utils::get_unimplemented_payment_method_error_message("deutschebank"), + ) + .into()), + } + } else { + Err(errors::ConnectorError::MissingRequiredField { + field_name: "setup_future_usage or customer_acceptance.acceptance_type", } - _ => Err(errors::ConnectorError::NotImplemented( - utils::get_unimplemented_payment_method_error_message("deutschebank"), - ) - .into()), + .into()) } } Some(api_models::payments::MandateReferenceId::ConnectorMandateId(mandate_data)) => { From c3f991040737d5ed677678b3b07cfb7c1eb6f1cb Mon Sep 17 00:00:00 2001 From: deepanshu-iiitu Date: Fri, 20 Sep 2024 12:32:41 +0530 Subject: [PATCH 08/11] chore: Remove already added util --- crates/hyperswitch_connectors/src/utils.rs | 271 +-------------------- 1 file changed, 1 insertion(+), 270 deletions(-) diff --git a/crates/hyperswitch_connectors/src/utils.rs b/crates/hyperswitch_connectors/src/utils.rs index 2fcb166397dd..a60a0d73ff3c 100644 --- a/crates/hyperswitch_connectors/src/utils.rs +++ b/crates/hyperswitch_connectors/src/utils.rs @@ -16,11 +16,7 @@ use common_utils::{ }; use error_stack::{report, ResultExt}; use hyperswitch_domain_models::{ - payment_method_data::{ - BankDebitData, BankRedirectData, BankTransferData, Card, CardRedirectData, GiftCardData, - OpenBankingData, PayLaterData, PaymentMethodData, RealTimePaymentData, VoucherData, - WalletData, - }, + payment_method_data::{Card, PaymentMethodData}, router_data::{PaymentMethodToken, RecurringMandatePaymentData}, router_request_types::{ AuthenticationData, BrowserInformation, CompleteAuthorizeData, PaymentsAuthorizeData, @@ -1363,271 +1359,6 @@ impl PaymentsCompleteAuthorizeRequestData for CompleteAuthorizeData { } } -pub fn is_mandate_supported( - selected_pmd: PaymentMethodData, - payment_method_type: Option, - mandate_implemented_pmds: std::collections::HashSet, - connector: &'static str, -) -> Result<(), Error> { - if mandate_implemented_pmds.contains(&PaymentMethodDataType::from(selected_pmd.clone())) { - Ok(()) - } else { - match payment_method_type { - Some(pm_type) => Err(errors::ConnectorError::NotSupported { - message: format!("{} mandate payment", pm_type), - connector, - } - .into()), - None => Err(errors::ConnectorError::NotSupported { - message: " mandate payment".to_string(), - connector, - } - .into()), - } - } -} - -#[derive(Debug, strum::Display, Eq, PartialEq, Hash)] -pub enum PaymentMethodDataType { - Card, - Knet, - Benefit, - MomoAtm, - CardRedirect, - AliPayQr, - AliPayRedirect, - AliPayHkRedirect, - MomoRedirect, - KakaoPayRedirect, - GoPayRedirect, - GcashRedirect, - ApplePay, - ApplePayRedirect, - ApplePayThirdPartySdk, - DanaRedirect, - DuitNow, - GooglePay, - GooglePayRedirect, - GooglePayThirdPartySdk, - MbWayRedirect, - MobilePayRedirect, - PaypalRedirect, - PaypalSdk, - SamsungPay, - TwintRedirect, - VippsRedirect, - TouchNGoRedirect, - WeChatPayRedirect, - WeChatPayQr, - CashappQr, - SwishQr, - KlarnaRedirect, - KlarnaSdk, - AffirmRedirect, - AfterpayClearpayRedirect, - PayBrightRedirect, - WalleyRedirect, - AlmaRedirect, - AtomeRedirect, - BancontactCard, - Bizum, - Blik, - Eps, - Giropay, - Ideal, - Interac, - LocalBankRedirect, - OnlineBankingCzechRepublic, - OnlineBankingFinland, - OnlineBankingPoland, - OnlineBankingSlovakia, - OpenBankingUk, - Przelewy24, - Sofort, - Trustly, - OnlineBankingFpx, - OnlineBankingThailand, - AchBankDebit, - SepaBankDebit, - BecsBankDebit, - BacsBankDebit, - AchBankTransfer, - SepaBankTransfer, - BacsBankTransfer, - MultibancoBankTransfer, - PermataBankTransfer, - BcaBankTransfer, - BniVaBankTransfer, - BriVaBankTransfer, - CimbVaBankTransfer, - DanamonVaBankTransfer, - MandiriVaBankTransfer, - Pix, - Pse, - Crypto, - MandatePayment, - Reward, - Upi, - Boleto, - Efecty, - PagoEfectivo, - RedCompra, - RedPagos, - Alfamart, - Indomaret, - Oxxo, - SevenEleven, - Lawson, - MiniStop, - FamilyMart, - Seicomart, - PayEasy, - Givex, - PaySafeCar, - CardToken, - LocalBankTransfer, - Mifinity, - Fps, - PromptPay, - VietQr, - OpenBanking, - NetworkToken, -} - -impl From for PaymentMethodDataType { - fn from(pm_data: PaymentMethodData) -> Self { - match pm_data { - PaymentMethodData::Card(_) => Self::Card, - PaymentMethodData::NetworkToken(_) => Self::NetworkToken, - PaymentMethodData::CardRedirect(card_redirect_data) => match card_redirect_data { - CardRedirectData::Knet {} => Self::Knet, - CardRedirectData::Benefit {} => Self::Benefit, - CardRedirectData::MomoAtm {} => Self::MomoAtm, - CardRedirectData::CardRedirect {} => Self::CardRedirect, - }, - PaymentMethodData::Wallet(wallet_data) => match wallet_data { - WalletData::AliPayQr(_) => Self::AliPayQr, - WalletData::AliPayRedirect(_) => Self::AliPayRedirect, - WalletData::AliPayHkRedirect(_) => Self::AliPayHkRedirect, - WalletData::MomoRedirect(_) => Self::MomoRedirect, - WalletData::KakaoPayRedirect(_) => Self::KakaoPayRedirect, - WalletData::GoPayRedirect(_) => Self::GoPayRedirect, - WalletData::GcashRedirect(_) => Self::GcashRedirect, - WalletData::ApplePay(_) => Self::ApplePay, - WalletData::ApplePayRedirect(_) => Self::ApplePayRedirect, - WalletData::ApplePayThirdPartySdk(_) => Self::ApplePayThirdPartySdk, - WalletData::DanaRedirect {} => Self::DanaRedirect, - WalletData::GooglePay(_) => Self::GooglePay, - WalletData::GooglePayRedirect(_) => Self::GooglePayRedirect, - WalletData::GooglePayThirdPartySdk(_) => Self::GooglePayThirdPartySdk, - WalletData::MbWayRedirect(_) => Self::MbWayRedirect, - WalletData::MobilePayRedirect(_) => Self::MobilePayRedirect, - WalletData::PaypalRedirect(_) => Self::PaypalRedirect, - WalletData::PaypalSdk(_) => Self::PaypalSdk, - WalletData::SamsungPay(_) => Self::SamsungPay, - WalletData::TwintRedirect {} => Self::TwintRedirect, - WalletData::VippsRedirect {} => Self::VippsRedirect, - WalletData::TouchNGoRedirect(_) => Self::TouchNGoRedirect, - WalletData::WeChatPayRedirect(_) => Self::WeChatPayRedirect, - WalletData::WeChatPayQr(_) => Self::WeChatPayQr, - WalletData::CashappQr(_) => Self::CashappQr, - WalletData::SwishQr(_) => Self::SwishQr, - WalletData::Mifinity(_) => Self::Mifinity, - }, - PaymentMethodData::PayLater(pay_later_data) => match pay_later_data { - PayLaterData::KlarnaRedirect { .. } => Self::KlarnaRedirect, - PayLaterData::KlarnaSdk { .. } => Self::KlarnaSdk, - PayLaterData::AffirmRedirect {} => Self::AffirmRedirect, - PayLaterData::AfterpayClearpayRedirect { .. } => Self::AfterpayClearpayRedirect, - PayLaterData::PayBrightRedirect {} => Self::PayBrightRedirect, - PayLaterData::WalleyRedirect {} => Self::WalleyRedirect, - PayLaterData::AlmaRedirect {} => Self::AlmaRedirect, - PayLaterData::AtomeRedirect {} => Self::AtomeRedirect, - }, - PaymentMethodData::BankRedirect(bank_redirect_data) => match bank_redirect_data { - BankRedirectData::BancontactCard { .. } => Self::BancontactCard, - BankRedirectData::Bizum {} => Self::Bizum, - BankRedirectData::Blik { .. } => Self::Blik, - BankRedirectData::Eps { .. } => Self::Eps, - BankRedirectData::Giropay { .. } => Self::Giropay, - BankRedirectData::Ideal { .. } => Self::Ideal, - BankRedirectData::Interac { .. } => Self::Interac, - BankRedirectData::OnlineBankingCzechRepublic { .. } => { - Self::OnlineBankingCzechRepublic - } - BankRedirectData::OnlineBankingFinland { .. } => Self::OnlineBankingFinland, - BankRedirectData::OnlineBankingPoland { .. } => Self::OnlineBankingPoland, - BankRedirectData::OnlineBankingSlovakia { .. } => Self::OnlineBankingSlovakia, - BankRedirectData::OpenBankingUk { .. } => Self::OpenBankingUk, - BankRedirectData::Przelewy24 { .. } => Self::Przelewy24, - BankRedirectData::Sofort { .. } => Self::Sofort, - BankRedirectData::Trustly { .. } => Self::Trustly, - BankRedirectData::OnlineBankingFpx { .. } => Self::OnlineBankingFpx, - BankRedirectData::OnlineBankingThailand { .. } => Self::OnlineBankingThailand, - BankRedirectData::LocalBankRedirect {} => Self::LocalBankRedirect, - }, - PaymentMethodData::BankDebit(bank_debit_data) => match bank_debit_data { - BankDebitData::AchBankDebit { .. } => Self::AchBankDebit, - BankDebitData::SepaBankDebit { .. } => Self::SepaBankDebit, - BankDebitData::BecsBankDebit { .. } => Self::BecsBankDebit, - BankDebitData::BacsBankDebit { .. } => Self::BacsBankDebit, - }, - PaymentMethodData::BankTransfer(bank_transfer_data) => match *bank_transfer_data { - BankTransferData::AchBankTransfer { .. } => Self::AchBankTransfer, - BankTransferData::SepaBankTransfer { .. } => Self::SepaBankTransfer, - BankTransferData::BacsBankTransfer { .. } => Self::BacsBankTransfer, - BankTransferData::MultibancoBankTransfer { .. } => Self::MultibancoBankTransfer, - BankTransferData::PermataBankTransfer { .. } => Self::PermataBankTransfer, - BankTransferData::BcaBankTransfer { .. } => Self::BcaBankTransfer, - BankTransferData::BniVaBankTransfer { .. } => Self::BniVaBankTransfer, - BankTransferData::BriVaBankTransfer { .. } => Self::BriVaBankTransfer, - BankTransferData::CimbVaBankTransfer { .. } => Self::CimbVaBankTransfer, - BankTransferData::DanamonVaBankTransfer { .. } => Self::DanamonVaBankTransfer, - BankTransferData::MandiriVaBankTransfer { .. } => Self::MandiriVaBankTransfer, - BankTransferData::Pix { .. } => Self::Pix, - BankTransferData::Pse {} => Self::Pse, - BankTransferData::LocalBankTransfer { .. } => Self::LocalBankTransfer, - }, - PaymentMethodData::Crypto(_) => Self::Crypto, - PaymentMethodData::MandatePayment => Self::MandatePayment, - PaymentMethodData::Reward => Self::Reward, - PaymentMethodData::Upi(_) => Self::Upi, - PaymentMethodData::Voucher(voucher_data) => match voucher_data { - VoucherData::Boleto(_) => Self::Boleto, - VoucherData::Efecty => Self::Efecty, - VoucherData::PagoEfectivo => Self::PagoEfectivo, - VoucherData::RedCompra => Self::RedCompra, - VoucherData::RedPagos => Self::RedPagos, - VoucherData::Alfamart(_) => Self::Alfamart, - VoucherData::Indomaret(_) => Self::Indomaret, - VoucherData::Oxxo => Self::Oxxo, - VoucherData::SevenEleven(_) => Self::SevenEleven, - VoucherData::Lawson(_) => Self::Lawson, - VoucherData::MiniStop(_) => Self::MiniStop, - VoucherData::FamilyMart(_) => Self::FamilyMart, - VoucherData::Seicomart(_) => Self::Seicomart, - VoucherData::PayEasy(_) => Self::PayEasy, - }, - PaymentMethodData::RealTimePayment(real_time_payment_data) => { - match *real_time_payment_data { - RealTimePaymentData::DuitNow {} => Self::DuitNow, - RealTimePaymentData::Fps {} => Self::Fps, - RealTimePaymentData::PromptPay {} => Self::PromptPay, - RealTimePaymentData::VietQr {} => Self::VietQr, - } - } - PaymentMethodData::GiftCard(gift_card_data) => match *gift_card_data { - GiftCardData::Givex(_) => Self::Givex, - GiftCardData::PaySafeCard {} => Self::PaySafeCar, - }, - PaymentMethodData::CardToken(_) => Self::CardToken, - PaymentMethodData::OpenBanking(data) => match data { - OpenBankingData::OpenBankingPIS {} => Self::OpenBanking, - }, - } - } -} - pub trait BrowserInformationData { fn get_accept_header(&self) -> Result; fn get_language(&self) -> Result; From 3861578a3581eaff8e495b84d472da4627ceea6c Mon Sep 17 00:00:00 2001 From: deepanshu-iiitu Date: Fri, 20 Sep 2024 12:33:41 +0530 Subject: [PATCH 09/11] Merge branch 'main' into mandate-sepa-deutsche From aaf00806fd40c98d3b66fc4f712646aab248521b Mon Sep 17 00:00:00 2001 From: deepanshu-iiitu Date: Fri, 20 Sep 2024 12:48:22 +0530 Subject: [PATCH 10/11] chore: Resolve merge conflicts --- .../src/connectors/novalnet/transformers.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/hyperswitch_connectors/src/connectors/novalnet/transformers.rs b/crates/hyperswitch_connectors/src/connectors/novalnet/transformers.rs index b400555305d3..56da53c2873e 100644 --- a/crates/hyperswitch_connectors/src/connectors/novalnet/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/novalnet/transformers.rs @@ -787,6 +787,7 @@ impl MandateReference { connector_mandate_id: Some(id.clone()), payment_method_id: None, + mandate_metadata: None, } }), connector_metadata: None, From 90a420f6f504df8b3856efe395dd3811c975d17a Mon Sep 17 00:00:00 2001 From: deepanshu-iiitu Date: Fri, 20 Sep 2024 16:30:34 +0530 Subject: [PATCH 11/11] fix(connector): [DEUTSCHE] Trim spaces in IBAN --- .../src/connectors/deutschebank/transformers.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs b/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs index 8b3837edd630..30b1d65134a3 100644 --- a/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/deutschebank/transformers.rs @@ -155,7 +155,7 @@ impl TryFrom<&DeutschebankRouterData<&PaymentsAuthorizeRouterData>> Ok(Self::MandatePost(DeutschebankMandatePostRequest { approval_by: DeutschebankSEPAApproval::Click, email_address: item.router_data.request.get_email()?, - iban, + iban: Secret::from(iban.peek().replace(" ", "")), first_name: billing_address.get_first_name()?.clone(), last_name: billing_address.get_last_name()?.clone(), })) @@ -313,7 +313,7 @@ impl PaymentMethodData::BankDebit(BankDebitData::SepaBankDebit { iban, .. - }) => Ok(iban), + }) => Ok(Secret::from(iban.peek().replace(" ", ""))), _ => Err(errors::ConnectorError::MissingRequiredField { field_name: "payment_method_data.bank_debit.sepa_bank_debit.iban" @@ -470,7 +470,7 @@ impl TryFrom<&DeutschebankRouterData<&PaymentsCompleteAuthorizeRouterData>> means_of_payment: DeutschebankMeansOfPayment { bank_account: DeutschebankBankAccount { account_holder, - iban, + iban: Secret::from(iban.peek().replace(" ", "")), }, }, mandate: {