Skip to content

Commit

Permalink
refactor(bank-debit): remove billingdetails from bankdebit pmd (#4371)
Browse files Browse the repository at this point in the history
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
  • Loading branch information
swangi-kumari and hyperswitch-bot[bot] committed May 8, 2024
1 parent 3e1c7eb commit 625b531
Show file tree
Hide file tree
Showing 12 changed files with 142 additions and 289 deletions.
42 changes: 23 additions & 19 deletions crates/api_models/src/payments.rs
Expand Up @@ -1148,7 +1148,7 @@ pub enum BankDebitData {
/// Payment Method data for Ach bank debit
AchBankDebit {
/// Billing details for bank debit
billing_details: BankDebitBilling,
billing_details: Option<BankDebitBilling>,
/// Account number for ach bank debit payment
#[schema(value_type = String, example = "000123456789")]
account_number: Secret<String>,
Expand All @@ -1173,7 +1173,7 @@ pub enum BankDebitData {
},
SepaBankDebit {
/// Billing details for bank debit
billing_details: BankDebitBilling,
billing_details: Option<BankDebitBilling>,
/// International bank account number (iban) for SEPA
#[schema(value_type = String, example = "DE89370400440532013000")]
iban: Secret<String>,
Expand All @@ -1183,7 +1183,7 @@ pub enum BankDebitData {
},
BecsBankDebit {
/// Billing details for bank debit
billing_details: BankDebitBilling,
billing_details: Option<BankDebitBilling>,
/// Account number for Becs payment method
#[schema(value_type = String, example = "000123456")]
account_number: Secret<String>,
Expand All @@ -1196,7 +1196,7 @@ pub enum BankDebitData {
},
BacsBankDebit {
/// Billing details for bank debit
billing_details: BankDebitBilling,
billing_details: Option<BankDebitBilling>,
/// Account number for Bacs payment method
#[schema(value_type = String, example = "00012345")]
account_number: Secret<String>,
Expand All @@ -1212,11 +1212,12 @@ pub enum BankDebitData {
impl GetAddressFromPaymentMethodData for BankDebitData {
fn get_billing_address(&self) -> Option<Address> {
fn get_billing_address_inner(
bank_debit_billing: &BankDebitBilling,
bank_debit_billing: Option<&BankDebitBilling>,
bank_account_holder_name: Option<&Secret<String>>,
) -> Option<Address> {
// We will always have address here
let mut address = bank_debit_billing.get_billing_address()?;
let mut address = bank_debit_billing
.and_then(GetAddressFromPaymentMethodData::get_billing_address)?;

// Prefer `account_holder_name` over `name`
address.address.as_mut().map(|address| {
Expand Down Expand Up @@ -1248,7 +1249,10 @@ impl GetAddressFromPaymentMethodData for BankDebitData {
billing_details,
bank_account_holder_name,
..
} => get_billing_address_inner(billing_details, bank_account_holder_name.as_ref()),
} => get_billing_address_inner(
billing_details.as_ref(),
bank_account_holder_name.as_ref(),
),
}
}
}
Expand Down Expand Up @@ -1447,7 +1451,7 @@ impl GetAddressFromPaymentMethodData for PaymentMethodData {
Self::Wallet(wallet_data) => wallet_data.get_billing_address(),
Self::PayLater(pay_later) => pay_later.get_billing_address(),
Self::BankRedirect(_) => None,
Self::BankDebit(_) => None,
Self::BankDebit(bank_debit_data) => bank_debit_data.get_billing_address(),
Self::BankTransfer(_) => None,
Self::Voucher(voucher_data) => voucher_data.get_billing_address(),
Self::Crypto(_)
Expand Down Expand Up @@ -2241,31 +2245,31 @@ impl GetAddressFromPaymentMethodData for BankTransferData {
#[derive(serde::Deserialize, serde::Serialize, Debug, Clone, ToSchema, Eq, PartialEq)]
pub struct BankDebitBilling {
/// The billing name for bank debits
#[schema(value_type = String, example = "John Doe")]
pub name: Secret<String>,
#[schema(value_type = Option<String>, example = "John Doe")]
pub name: Option<Secret<String>>,
/// The billing email for bank debits
#[schema(value_type = String, example = "example@example.com")]
pub email: Email,
#[schema(value_type = Option<String>, example = "example@example.com")]
pub email: Option<Email>,
/// The billing address for bank debits
pub address: Option<AddressDetails>,
}

impl GetAddressFromPaymentMethodData for BankDebitBilling {
fn get_billing_address(&self) -> Option<Address> {
let address = if let Some(mut address) = self.address.clone() {
address.first_name = Some(self.name.clone());
address.first_name = self.name.clone().or(address.first_name);
Address {
address: Some(address),
email: Some(self.email.clone()),
email: self.email.clone(),
phone: None,
}
} else {
Address {
address: Some(AddressDetails {
first_name: Some(self.name.clone()),
first_name: self.name.clone(),
..AddressDetails::default()
}),
email: Some(self.email.clone()),
email: self.email.clone(),
phone: None,
}
};
Expand Down Expand Up @@ -4898,14 +4902,14 @@ mod billing_from_payment_method_data {
let test_first_name = Secret::new(String::from("Chaser"));

let bank_redirect_billing = BankDebitBilling {
name: test_first_name.clone(),
name: Some(test_first_name.clone()),
address: None,
email: test_email.clone(),
email: Some(test_email.clone()),
};

let ach_bank_debit_payment_method_data =
PaymentMethodData::BankDebit(BankDebitData::AchBankDebit {
billing_details: bank_redirect_billing,
billing_details: Some(bank_redirect_billing),
account_number: Secret::new("1234".to_string()),
routing_number: Secret::new("1235".to_string()),
card_holder_name: None,
Expand Down
42 changes: 14 additions & 28 deletions crates/router/src/connector/adyen/transformers.rs
Expand Up @@ -1820,56 +1820,42 @@ fn build_shopper_reference(customer_id: &Option<String>, merchant_id: String) ->
.map(|c_id| format!("{}_{}", merchant_id, c_id))
}

impl<'a> TryFrom<&domain::BankDebitData> for AdyenPaymentMethod<'a> {
impl<'a> TryFrom<(&domain::BankDebitData, &types::PaymentsAuthorizeRouterData)>
for AdyenPaymentMethod<'a>
{
type Error = Error;
fn try_from(bank_debit_data: &domain::BankDebitData) -> Result<Self, Self::Error> {
fn try_from(
(bank_debit_data, item): (&domain::BankDebitData, &types::PaymentsAuthorizeRouterData),
) -> Result<Self, Self::Error> {
match bank_debit_data {
domain::BankDebitData::AchBankDebit {
account_number,
routing_number,
card_holder_name,
..
} => Ok(AdyenPaymentMethod::AchDirectDebit(Box::new(
AchDirectDebitData {
payment_type: PaymentType::AchDirectDebit,
bank_account_number: account_number.clone(),
bank_location_id: routing_number.clone(),
owner_name: card_holder_name.clone().ok_or(
errors::ConnectorError::MissingRequiredField {
field_name: "card_holder_name",
},
)?,
owner_name: item.get_billing_full_name()?,
},
))),
domain::BankDebitData::SepaBankDebit {
iban,
bank_account_holder_name,
..
} => Ok(AdyenPaymentMethod::SepaDirectDebit(Box::new(
SepaDirectDebitData {
owner_name: bank_account_holder_name.clone().ok_or(
errors::ConnectorError::MissingRequiredField {
field_name: "bank_account_holder_name",
},
)?,
domain::BankDebitData::SepaBankDebit { iban, .. } => Ok(
AdyenPaymentMethod::SepaDirectDebit(Box::new(SepaDirectDebitData {
owner_name: item.get_billing_full_name()?,
iban_number: iban.clone(),
},
))),
})),
),
domain::BankDebitData::BacsBankDebit {
account_number,
sort_code,
bank_account_holder_name,
..
} => Ok(AdyenPaymentMethod::BacsDirectDebit(Box::new(
BacsDirectDebitData {
payment_type: PaymentType::BacsDirectDebit,
bank_account_number: account_number.clone(),
bank_location_id: sort_code.clone(),
holder_name: bank_account_holder_name.clone().ok_or(
errors::ConnectorError::MissingRequiredField {
field_name: "bank_account_holder_name",
},
)?,
holder_name: item.get_billing_full_name()?,
},
))),
domain::BankDebitData::BecsBankDebit { .. } => {
Expand Down Expand Up @@ -2713,7 +2699,7 @@ impl<'a>
let browser_info = get_browser_info(item.router_data)?;
let additional_data = get_additional_data(item.router_data);
let return_url = item.router_data.request.get_return_url()?;
let payment_method = AdyenPaymentMethod::try_from(bank_debit_data)?;
let payment_method = AdyenPaymentMethod::try_from((bank_debit_data, item.router_data))?;
let country_code = get_country_code(item.router_data.get_optional_billing());
let request = AdyenPaymentRequest {
amount,
Expand Down
103 changes: 18 additions & 85 deletions crates/router/src/connector/gocardless/transformers.rs
Expand Up @@ -8,9 +8,8 @@ use serde::{Deserialize, Serialize};

use crate::{
connector::utils::{
self, AddressDetailsData, BankDirectDebitBillingData, BrowserInformationData,
ConnectorCustomerData, PaymentsAuthorizeRequestData, PaymentsSetupMandateRequestData,
RouterData,
self, AddressDetailsData, BrowserInformationData, ConnectorCustomerData,
PaymentsAuthorizeRequestData, PaymentsSetupMandateRequestData, RouterData,
},
core::errors,
types::{
Expand Down Expand Up @@ -67,64 +66,19 @@ impl TryFrom<&types::ConnectorCustomerRouterData> for GocardlessCustomerRequest
type Error = error_stack::Report<errors::ConnectorError>;
fn try_from(item: &types::ConnectorCustomerRouterData) -> Result<Self, Self::Error> {
let email = item.request.get_email()?;
let billing_details = match &item.request.payment_method_data {
domain::PaymentMethodData::BankDebit(bank_debit_data) => {
match bank_debit_data.clone() {
domain::BankDebitData::AchBankDebit {
billing_details, ..
} => Ok(billing_details),
domain::BankDebitData::SepaBankDebit {
billing_details, ..
} => Ok(billing_details),
domain::BankDebitData::BecsBankDebit {
billing_details, ..
} => Ok(billing_details),
domain::BankDebitData::BacsBankDebit { .. } => {
Err(errors::ConnectorError::NotImplemented(
utils::get_unimplemented_payment_method_error_message("Gocardless"),
))
}
}
}
domain::PaymentMethodData::Card(_)
| domain::PaymentMethodData::CardRedirect(_)
| domain::PaymentMethodData::Wallet(_)
| domain::PaymentMethodData::PayLater(_)
| domain::PaymentMethodData::BankRedirect(_)
| domain::PaymentMethodData::BankTransfer(_)
| domain::PaymentMethodData::Crypto(_)
| domain::PaymentMethodData::MandatePayment
| domain::PaymentMethodData::Reward
| domain::PaymentMethodData::Upi(_)
| domain::PaymentMethodData::Voucher(_)
| domain::PaymentMethodData::GiftCard(_)
| domain::PaymentMethodData::CardToken(_) => {
Err(errors::ConnectorError::NotImplemented(
utils::get_unimplemented_payment_method_error_message("Gocardless"),
))
}
}?;

let billing_details_name = billing_details.name.expose();
let billing_details_name = item.get_billing_full_name()?.expose();

if billing_details_name.is_empty() {
Err(errors::ConnectorError::MissingRequiredField {
field_name: "billing_details.name",
})?
}
let (given_name, family_name) = billing_details_name
.trim()
.rsplit_once(' ')
.unwrap_or((&billing_details_name, &billing_details_name));

let billing_address = billing_details
.address
.ok_or_else(utils::missing_field_err("billing_details.address"))?;
let billing_address = item.get_billing_address()?;

let metadata = CustomerMetaData {
crm_id: item.customer_id.clone().map(Secret::new),
};
let region = get_region(&billing_address)?;
let region = get_region(billing_address)?;
Ok(Self {
customers: GocardlessCustomer {
email,
Expand All @@ -141,7 +95,7 @@ impl TryFrom<&types::ConnectorCustomerRouterData> for GocardlessCustomerRequest
postal_code: billing_address.zip.to_owned(),
// Should be populated based on the billing country
swedish_identity_number: None,
city: billing_address.city.map(Secret::new),
city: billing_address.city.clone().map(Secret::new),
},
})
}
Expand Down Expand Up @@ -274,7 +228,7 @@ impl TryFrom<&types::TokenizationRouterData> for CustomerBankAccount {
fn try_from(item: &types::TokenizationRouterData) -> Result<Self, Self::Error> {
match &item.request.payment_method_data {
domain::PaymentMethodData::BankDebit(bank_debit_data) => {
Self::try_from(bank_debit_data)
Self::try_from((bank_debit_data, item))
}
domain::PaymentMethodData::Card(_)
| domain::PaymentMethodData::CardRedirect(_)
Expand All @@ -298,26 +252,21 @@ impl TryFrom<&types::TokenizationRouterData> for CustomerBankAccount {
}
}

impl TryFrom<&domain::BankDebitData> for CustomerBankAccount {
impl TryFrom<(&domain::BankDebitData, &types::TokenizationRouterData)> for CustomerBankAccount {
type Error = error_stack::Report<errors::ConnectorError>;
fn try_from(item: &domain::BankDebitData) -> Result<Self, Self::Error> {
match item {
fn try_from(
(bank_debit_data, item): (&domain::BankDebitData, &types::TokenizationRouterData),
) -> Result<Self, Self::Error> {
match bank_debit_data {
domain::BankDebitData::AchBankDebit {
billing_details,
account_number,
routing_number,
bank_type,
bank_account_holder_name,
..
} => {
let bank_type = bank_type.ok_or_else(utils::missing_field_err("bank_type"))?;
let country_code = billing_details.get_billing_country()?;
let account_holder_name =
bank_account_holder_name
.clone()
.ok_or_else(utils::missing_field_err(
"payment_method_data.bank_debit.ach_bank_debit.bank_account_holder_name",
))?;
let country_code = item.get_billing_country()?;
let account_holder_name = item.get_billing_full_name()?;
let us_bank_account = USBankAccount {
country_code,
account_number: account_number.clone(),
Expand All @@ -328,18 +277,11 @@ impl TryFrom<&domain::BankDebitData> for CustomerBankAccount {
Ok(Self::USBankAccount(us_bank_account))
}
domain::BankDebitData::BecsBankDebit {
billing_details,
account_number,
bsb_number,
bank_account_holder_name,
} => {
let country_code = billing_details.get_billing_country()?;
let account_holder_name =
bank_account_holder_name
.clone()
.ok_or_else(utils::missing_field_err(
"payment_method_data.bank_debit.becs_bank_debit.bank_account_holder_name",
))?;
let country_code = item.get_billing_country()?;
let account_holder_name = item.get_billing_full_name()?;
let au_bank_account = AUBankAccount {
country_code,
account_number: account_number.clone(),
Expand All @@ -348,17 +290,8 @@ impl TryFrom<&domain::BankDebitData> for CustomerBankAccount {
};
Ok(Self::AUBankAccount(au_bank_account))
}
domain::BankDebitData::SepaBankDebit {
iban,
bank_account_holder_name,
..
} => {
let account_holder_name =
bank_account_holder_name
.clone()
.ok_or_else(utils::missing_field_err(
"payment_method_data.bank_debit.sepa_bank_debit.bank_account_holder_name",
))?;
domain::BankDebitData::SepaBankDebit { iban, .. } => {
let account_holder_name = item.get_billing_full_name()?;
let international_bank_account = InternationalBankAccount {
iban: iban.clone(),
account_holder_name,
Expand Down

0 comments on commit 625b531

Please sign in to comment.