diff --git a/config/development.toml b/config/development.toml index 7a6da9896b..f5bd1c1ab3 100644 --- a/config/development.toml +++ b/config/development.toml @@ -453,7 +453,7 @@ square = { long_lived_token = false, payment_method = "card" } braintree = { long_lived_token = false, payment_method = "card" } payme = { long_lived_token = false, payment_method = "card" } gocardless = { long_lived_token = true, payment_method = "bank_debit" } -billwerk = {long_lived_token = false, payment_method = "card"} +billwerk = { long_lived_token = false, payment_method = "card" } [temp_locker_enable_config] stripe = { payment_method = "bank_transfer" } diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index 6805363b26..549b5d7b04 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -4,10 +4,10 @@ use cards::CardNumber; use common_utils::{ consts::default_payments_list_limit, crypto, - ext_traits::Encode, + ext_traits::{ConfigExt, Encode}, pii::{self, Email}, }; -use masking::Secret; +use masking::{PeekInterface, Secret}; use router_derive::Setter; use serde::{ de::{self, Unexpected, Visitor}, @@ -909,6 +909,47 @@ pub struct Card { pub nick_name: Option>, } +impl GetAddressFromPaymentMethodData for Card { + fn get_billing_address(&self) -> Option
{ + // Create billing address if first_name is some or if it is not "" + self.card_holder_name + .as_ref() + .filter(|card_holder_name| !card_holder_name.is_empty_after_trim()) + .map(|card_holder_name| { + // Split the `card_holder_name` into `first_name` and `last_name` based on the + // first occurrence of ' '. For example + // John Wheat Dough + // first_name -> John + // last_name -> Wheat Dough + card_holder_name.peek().split_whitespace() + }) + .map(|mut card_holder_name_iter| { + let first_name = card_holder_name_iter + .next() + .map(ToOwned::to_owned) + .map(Secret::new); + + let last_name = card_holder_name_iter.collect::>().join(" "); + let last_name = if last_name.is_empty_after_trim() { + None + } else { + Some(Secret::new(last_name)) + }; + + AddressDetails { + first_name, + last_name, + ..Default::default() + } + }) + .map(|address_details| Address { + address: Some(address_details), + phone: None, + email: None, + }) + } +} + impl Card { fn apply_additional_card_info(&self, additional_card_info: AdditionalCardInfo) -> Self { Self { @@ -1292,7 +1333,7 @@ pub trait GetAddressFromPaymentMethodData { impl GetAddressFromPaymentMethodData for PaymentMethodData { fn get_billing_address(&self) -> Option
{ match self { - Self::Card(_) => None, + Self::Card(card_data) => card_data.get_billing_address(), Self::CardRedirect(_) => None, Self::Wallet(_) => None, Self::PayLater(_) => None, @@ -2647,6 +2688,18 @@ pub struct AddressDetails { } impl AddressDetails { + pub fn get_optional_full_name(&self) -> Option> { + match (self.first_name.as_ref(), self.last_name.as_ref()) { + (Some(first_name), Some(last_name)) => Some(Secret::new(format!( + "{} {}", + first_name.peek(), + last_name.peek() + ))), + (Some(name), None) | (None, Some(name)) => Some(name.to_owned()), + _ => None, + } + } + pub fn unify_address_details(self, other: Option<&Self>) -> Self { if let Some(other) = other { let (first_name, last_name) = if self.first_name.is_some() { @@ -4591,11 +4644,15 @@ mod payments_request_api_contract { mod billing_from_payment_method_data { #![allow(clippy::unwrap_used)] use common_enums::CountryAlpha2; + use masking::ExposeOptionInterface; use super::*; const TEST_COUNTRY: CountryAlpha2 = CountryAlpha2::US; const TEST_FIRST_NAME: &str = "John"; + const TEST_LAST_NAME: &str = "Wheat Dough"; + const TEST_FULL_NAME: &str = "John Wheat Dough"; + const TEST_FIRST_NAME_SINGLE: &str = "John"; #[test] fn test_wallet_payment_method_data_paypal() { @@ -4704,15 +4761,17 @@ mod billing_from_payment_method_data { #[test] fn test_card_payment_method_data() { let card_payment_method_data = PaymentMethodData::Card(Card { - card_holder_name: Some(Secret::new(TEST_FIRST_NAME.into())), + card_holder_name: Some(Secret::new(TEST_FIRST_NAME_SINGLE.into())), ..Default::default() }); - let billing_address = card_payment_method_data.get_billing_address().unwrap(); + let billing_address = card_payment_method_data.get_billing_address(); + + let billing_address = billing_address.unwrap(); assert_eq!( - billing_address.address.unwrap().first_name.unwrap(), - Secret::new(TEST_FIRST_NAME.into()) + billing_address.address.unwrap().first_name.expose_option(), + Some(TEST_FIRST_NAME_SINGLE.into()) ); } @@ -4724,4 +4783,37 @@ mod billing_from_payment_method_data { assert!(billing_address.is_none()); } + + #[test] + fn test_card_payment_method_data_full_name() { + let card_payment_method_data = PaymentMethodData::Card(Card { + card_holder_name: Some(Secret::new(TEST_FULL_NAME.into())), + ..Default::default() + }); + + let billing_details = card_payment_method_data.get_billing_address().unwrap(); + let billing_address = billing_details.address.unwrap(); + + assert_eq!( + billing_address.first_name.expose_option(), + Some(TEST_FIRST_NAME.into()) + ); + + assert_eq!( + billing_address.last_name.expose_option(), + Some(TEST_LAST_NAME.into()) + ); + } + + #[test] + fn test_card_payment_method_data_empty_string() { + let card_payment_method_data = PaymentMethodData::Card(Card { + card_holder_name: Some(Secret::new("".to_string())), + ..Default::default() + }); + + let billing_details = card_payment_method_data.get_billing_address(); + + assert!(billing_details.is_none()); + } } diff --git a/crates/router/src/connector/aci/transformers.rs b/crates/router/src/connector/aci/transformers.rs index b8f3af6914..a4c17fb927 100644 --- a/crates/router/src/connector/aci/transformers.rs +++ b/crates/router/src/connector/aci/transformers.rs @@ -297,14 +297,14 @@ impl } } -impl TryFrom for PaymentDetails { +impl TryFrom<(domain::payments::Card, Option>)> for PaymentDetails { type Error = Error; - fn try_from(card_data: domain::payments::Card) -> Result { + fn try_from( + (card_data, card_holder_name): (domain::payments::Card, Option>), + ) -> Result { Ok(Self::AciCard(Box::new(CardDetails { card_number: card_data.card_number, - card_holder: card_data - .card_holder_name - .unwrap_or(Secret::new("".to_string())), + card_holder: card_holder_name.unwrap_or(Secret::new("".to_string())), card_expiry_month: card_data.card_exp_month, card_expiry_year: card_data.card_exp_year, card_cvv: card_data.card_cvc, @@ -563,8 +563,9 @@ impl ), ) -> Result { let (item, card_data) = value; + let card_holder_name = item.router_data.get_optional_billing_full_name(); let txn_details = get_transaction_details(item)?; - let payment_method = PaymentDetails::try_from(card_data.clone())?; + let payment_method = PaymentDetails::try_from((card_data.clone(), card_holder_name))?; let instruction = get_instruction_details(item); Ok(Self { diff --git a/crates/router/src/connector/adyen/transformers.rs b/crates/router/src/connector/adyen/transformers.rs index e47b570a06..cf39d9f5bb 100644 --- a/crates/router/src/connector/adyen/transformers.rs +++ b/crates/router/src/connector/adyen/transformers.rs @@ -1955,16 +1955,18 @@ impl<'a> TryFrom<&api_models::payments::GiftCardData> for AdyenPaymentMethod<'a> } } -impl<'a> TryFrom<&domain::Card> for AdyenPaymentMethod<'a> { +impl<'a> TryFrom<(&domain::Card, Option>)> for AdyenPaymentMethod<'a> { type Error = Error; - fn try_from(card: &domain::Card) -> Result { + fn try_from( + (card, card_holder_name): (&domain::Card, Option>), + ) -> Result { let adyen_card = AdyenCard { payment_type: PaymentType::Scheme, number: card.card_number.clone(), expiry_month: card.card_exp_month.clone(), expiry_year: card.get_expiry_year_4_digit(), cvc: Some(card.card_cvc.clone()), - holder_name: card.card_holder_name.clone(), + holder_name: card_holder_name, brand: None, network_payment_reference: None, }; @@ -2557,13 +2559,14 @@ impl<'a> domain::PaymentMethodData::Card(ref card) => { let card_issuer = card.get_card_issuer()?; let brand = CardBrand::try_from(&card_issuer)?; + let card_holder_name = item.router_data.get_optional_billing_full_name(); let adyen_card = AdyenCard { payment_type: PaymentType::Scheme, number: card.card_number.clone(), expiry_month: card.card_exp_month.clone(), expiry_year: card.card_exp_year.clone(), cvc: None, - holder_name: card.card_holder_name.clone(), + holder_name: card_holder_name, brand: Some(brand), network_payment_reference: Some(Secret::new(network_mandate_id)), }; @@ -2647,7 +2650,8 @@ impl<'a> let country_code = get_country_code(item.router_data.get_optional_billing()); 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(card_data)?; + let card_holder_name = item.router_data.get_optional_billing_full_name(); + let payment_method = AdyenPaymentMethod::try_from((card_data, card_holder_name))?; let shopper_email = item.router_data.request.email.clone(); let shopper_name = get_shopper_name(item.router_data.get_optional_billing()); diff --git a/crates/router/src/connector/bambora/transformers.rs b/crates/router/src/connector/bambora/transformers.rs index 42420cb340..3115f04f48 100644 --- a/crates/router/src/connector/bambora/transformers.rs +++ b/crates/router/src/connector/bambora/transformers.rs @@ -5,7 +5,7 @@ use masking::{ExposeInterface, PeekInterface, Secret}; use serde::{Deserialize, Deserializer, Serialize}; use crate::{ - connector::utils::{BrowserInformationData, PaymentsAuthorizeRequestData}, + connector::utils::{BrowserInformationData, PaymentsAuthorizeRequestData, RouterData}, consts, core::errors, services, @@ -117,8 +117,8 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for BamboraPaymentsRequest { enums::AuthenticationType::NoThreeDs => None, }; let bambora_card = BamboraCard { - name: req_card - .card_holder_name + name: item + .get_optional_billing_full_name() .unwrap_or(Secret::new("".to_string())), number: req_card.card_number, expiry_month: req_card.card_exp_month, diff --git a/crates/router/src/connector/braintree/braintree_graphql_transformers.rs b/crates/router/src/connector/braintree/braintree_graphql_transformers.rs index 0399a5d428..480867c6cb 100644 --- a/crates/router/src/connector/braintree/braintree_graphql_transformers.rs +++ b/crates/router/src/connector/braintree/braintree_graphql_transformers.rs @@ -868,8 +868,8 @@ impl TryFrom<&types::TokenizationRouterData> for BraintreeTokenRequest { expiration_year: card_data.card_exp_year, expiration_month: card_data.card_exp_month, cvv: card_data.card_cvc, - cardholder_name: card_data - .card_holder_name + cardholder_name: item + .get_optional_billing_full_name() .unwrap_or(Secret::new("".to_string())), }, }; diff --git a/crates/router/src/connector/dlocal/transformers.rs b/crates/router/src/connector/dlocal/transformers.rs index 20997f3a24..14337ca076 100644 --- a/crates/router/src/connector/dlocal/transformers.rs +++ b/crates/router/src/connector/dlocal/transformers.rs @@ -125,9 +125,9 @@ impl TryFrom<&DlocalRouterData<&types::PaymentsAuthorizeRouterData>> for DlocalP document: get_doc_from_currency(country.to_string()), }, card: Some(Card { - holder_name: ccard - .card_holder_name - .clone() + holder_name: item + .router_data + .get_optional_billing_full_name() .unwrap_or(Secret::new("".to_string())), number: ccard.card_number.clone(), cvv: ccard.card_cvc.clone(), diff --git a/crates/router/src/connector/dummyconnector/transformers.rs b/crates/router/src/connector/dummyconnector/transformers.rs index ed579f7a1c..52c9522842 100644 --- a/crates/router/src/connector/dummyconnector/transformers.rs +++ b/crates/router/src/connector/dummyconnector/transformers.rs @@ -4,6 +4,7 @@ use serde::{Deserialize, Serialize}; use url::Url; use crate::{ + connector::utils::RouterData, core::errors, services, types::{self, api, domain, storage::enums}, @@ -83,13 +84,13 @@ pub struct DummyConnectorCard { cvc: Secret, } -impl TryFrom for DummyConnectorCard { +impl TryFrom<(domain::Card, Option>)> for DummyConnectorCard { type Error = error_stack::Report; - fn try_from(value: domain::Card) -> Result { + fn try_from( + (value, card_holder_name): (domain::Card, Option>), + ) -> Result { Ok(Self { - name: value - .card_holder_name - .unwrap_or(Secret::new("".to_string())), + name: card_holder_name.unwrap_or(Secret::new("".to_string())), number: value.card_number, expiry_month: value.card_exp_month, expiry_year: value.card_exp_year, @@ -154,7 +155,11 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> .payment_method_data { domain::PaymentMethodData::Card(ref req_card) => { - Ok(PaymentMethodData::Card(req_card.clone().try_into()?)) + let card_holder_name = item.get_optional_billing_full_name(); + Ok(PaymentMethodData::Card(DummyConnectorCard::try_from(( + req_card.clone(), + card_holder_name, + ))?)) } domain::PaymentMethodData::Wallet(ref wallet_data) => { Ok(PaymentMethodData::Wallet(wallet_data.clone().try_into()?)) diff --git a/crates/router/src/connector/forte/transformers.rs b/crates/router/src/connector/forte/transformers.rs index 35f003233d..aef5ed32cf 100644 --- a/crates/router/src/connector/forte/transformers.rs +++ b/crates/router/src/connector/forte/transformers.rs @@ -80,9 +80,8 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for FortePaymentsRequest { let address = item.get_billing_address()?; let card = Card { card_type, - name_on_card: ccard - .card_holder_name - .clone() + name_on_card: item + .get_optional_billing_full_name() .unwrap_or(Secret::new("".to_string())), account_number: ccard.card_number.clone(), expire_month: ccard.card_exp_month.clone(), diff --git a/crates/router/src/connector/mollie/transformers.rs b/crates/router/src/connector/mollie/transformers.rs index 359320eb08..bca6ae360b 100644 --- a/crates/router/src/connector/mollie/transformers.rs +++ b/crates/router/src/connector/mollie/transformers.rs @@ -289,9 +289,8 @@ impl TryFrom<&types::TokenizationRouterData> for MollieCardTokenRequest { match item.request.payment_method_data.clone() { domain::PaymentMethodData::Card(ccard) => { let auth = MollieAuthType::try_from(&item.connector_auth_type)?; - let card_holder = ccard - .card_holder_name - .clone() + let card_holder = item + .get_optional_billing_full_name() .unwrap_or(Secret::new("".to_string())); let card_number = ccard.card_number.clone(); let card_expiry_date = diff --git a/crates/router/src/connector/noon/transformers.rs b/crates/router/src/connector/noon/transformers.rs index 08b0fff1c7..a240154a0f 100644 --- a/crates/router/src/connector/noon/transformers.rs +++ b/crates/router/src/connector/noon/transformers.rs @@ -241,7 +241,7 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for NoonPaymentsRequest { match item.request.payment_method_data.clone() { domain::PaymentMethodData::Card(req_card) => { Ok(NoonPaymentData::Card(NoonCard { - name_on_card: req_card.card_holder_name.clone(), + name_on_card: item.get_optional_billing_full_name(), number_plain: req_card.card_number.clone(), expiry_month: req_card.card_exp_month.clone(), expiry_year: req_card.get_expiry_year_4_digit(), diff --git a/crates/router/src/connector/nuvei/transformers.rs b/crates/router/src/connector/nuvei/transformers.rs index 08c3b8fbc9..f84b34f23a 100644 --- a/crates/router/src/connector/nuvei/transformers.rs +++ b/crates/router/src/connector/nuvei/transformers.rs @@ -427,6 +427,7 @@ impl pub struct NuveiCardDetails { card: domain::Card, three_d: Option, + card_holder_name: Option>, } impl TryFrom for NuveiPaymentsRequest { @@ -994,6 +995,7 @@ fn get_card_info( payment_option: PaymentOption::from(NuveiCardDetails { card: card_details.clone(), three_d, + card_holder_name: item.get_optional_billing_full_name(), }), billing_address, ..Default::default() @@ -1005,7 +1007,7 @@ impl From for PaymentOption { Self { card: Some(Card { card_number: Some(card.card_number), - card_holder_name: card.card_holder_name, + card_holder_name: card_details.card_holder_name, expiration_month: Some(card.card_exp_month), expiration_year: Some(card.card_exp_year), three_d: card_details.three_d, @@ -1030,6 +1032,7 @@ impl TryFrom<(&types::PaymentsCompleteAuthorizeRouterData, Secret)> payment_option: PaymentOption::from(NuveiCardDetails { card, three_d: None, + card_holder_name: item.get_optional_billing_full_name(), }), ..Default::default() }), diff --git a/crates/router/src/connector/opayo/transformers.rs b/crates/router/src/connector/opayo/transformers.rs index 008643f143..e00f9a331a 100644 --- a/crates/router/src/connector/opayo/transformers.rs +++ b/crates/router/src/connector/opayo/transformers.rs @@ -2,7 +2,7 @@ use masking::Secret; use serde::{Deserialize, Serialize}; use crate::{ - connector::utils::{self, PaymentsAuthorizeRequestData}, + connector::utils::{self, PaymentsAuthorizeRequestData, RouterData}, core::errors, types::{self, api, domain, storage::enums}, }; @@ -29,8 +29,8 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for OpayoPaymentsRequest { match item.request.payment_method_data.clone() { domain::PaymentMethodData::Card(req_card) => { let card = OpayoCard { - name: req_card - .card_holder_name + name: item + .get_optional_billing_full_name() .unwrap_or(Secret::new("".to_string())), number: req_card.card_number, expiry_month: req_card.card_exp_month, diff --git a/crates/router/src/connector/payeezy/transformers.rs b/crates/router/src/connector/payeezy/transformers.rs index 2b19b10b43..0ceed1390b 100644 --- a/crates/router/src/connector/payeezy/transformers.rs +++ b/crates/router/src/connector/payeezy/transformers.rs @@ -5,7 +5,7 @@ use masking::{ExposeInterface, Secret}; use serde::{Deserialize, Serialize}; use crate::{ - connector::utils::{self, CardData}, + connector::utils::{self, CardData, RouterData}, core::errors, types::{self, api, domain, storage::enums, transformers::ForeignFrom}, }; @@ -241,9 +241,9 @@ fn get_payment_method_data( let card_type = PayeezyCardType::try_from(card.get_card_issuer()?)?; let payeezy_card = PayeezyCard { card_type, - cardholder_name: card - .card_holder_name - .clone() + cardholder_name: item + .router_data + .get_optional_billing_full_name() .unwrap_or(Secret::new("".to_string())), card_number: card.card_number.clone(), exp_date: card.get_card_expiry_month_year_2_digit_with_delimiter("".to_string())?, diff --git a/crates/router/src/connector/paypal/transformers.rs b/crates/router/src/connector/paypal/transformers.rs index 6a3d396c83..94f18e6b8d 100644 --- a/crates/router/src/connector/paypal/transformers.rs +++ b/crates/router/src/connector/paypal/transformers.rs @@ -463,9 +463,9 @@ impl TryFrom<&PaypalRouterData<&types::PaymentsAuthorizeRouterData>> for PaypalP let payment_source = Some(PaymentSourceItem::Card(CardRequest { billing_address: get_address_info(item.router_data.get_optional_billing())?, expiry, - name: ccard - .card_holder_name - .clone() + name: item + .router_data + .get_optional_billing_full_name() .unwrap_or(Secret::new("".to_string())), number: Some(ccard.card_number.clone()), security_code: Some(ccard.card_cvc.clone()), diff --git a/crates/router/src/connector/powertranz/transformers.rs b/crates/router/src/connector/powertranz/transformers.rs index b8c20cf0fc..6b0675b161 100644 --- a/crates/router/src/connector/powertranz/transformers.rs +++ b/crates/router/src/connector/powertranz/transformers.rs @@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize}; use uuid::Uuid; use crate::{ - connector::utils::{self, CardData, PaymentsAuthorizeRequestData}, + connector::utils::{self, CardData, PaymentsAuthorizeRequestData, RouterData}, consts, core::errors, services, @@ -99,7 +99,10 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for PowertranzPaymentsRequest type Error = error_stack::Report; fn try_from(item: &types::PaymentsAuthorizeRouterData) -> Result { let source = match item.request.payment_method_data.clone() { - domain::PaymentMethodData::Card(card) => Source::try_from(&card), + domain::PaymentMethodData::Card(card) => { + let card_holder_name = item.get_optional_billing_full_name(); + Source::try_from((&card, card_holder_name)) + } domain::PaymentMethodData::Wallet(_) | domain::PaymentMethodData::CardRedirect(_) | domain::PaymentMethodData::PayLater(_) @@ -213,14 +216,13 @@ impl TryFrom<&types::BrowserInformation> for BrowserInfo { }) }*/ -impl TryFrom<&domain::Card> for Source { +impl TryFrom<(&domain::Card, Option>)> for Source { type Error = error_stack::Report; - fn try_from(card: &domain::Card) -> Result { + fn try_from( + (card, card_holder_name): (&domain::Card, Option>), + ) -> Result { let card = PowertranzCard { - cardholder_name: card - .card_holder_name - .clone() - .unwrap_or(Secret::new("".to_string())), + cardholder_name: card_holder_name.unwrap_or(Secret::new("".to_string())), card_pan: card.card_number.clone(), card_expiration: card.get_expiry_date_as_yymm()?, card_cvv: card.card_cvc.clone(), diff --git a/crates/router/src/connector/rapyd/transformers.rs b/crates/router/src/connector/rapyd/transformers.rs index 7950ff323a..04dc4496b6 100644 --- a/crates/router/src/connector/rapyd/transformers.rs +++ b/crates/router/src/connector/rapyd/transformers.rs @@ -4,7 +4,7 @@ use time::PrimitiveDateTime; use url::Url; use crate::{ - connector::utils::PaymentsAuthorizeRequestData, + connector::utils::{PaymentsAuthorizeRequestData, RouterData}, consts, core::errors, pii::Secret, @@ -131,8 +131,9 @@ impl TryFrom<&RapydRouterData<&types::PaymentsAuthorizeRouterData>> for RapydPay number: ccard.card_number.to_owned(), expiration_month: ccard.card_exp_month.to_owned(), expiration_year: ccard.card_exp_year.to_owned(), - name: ccard - .card_holder_name + name: item + .router_data + .get_optional_billing_full_name() .to_owned() .unwrap_or(Secret::new("".to_string())), cvv: ccard.card_cvc.to_owned(), diff --git a/crates/router/src/connector/shift4/transformers.rs b/crates/router/src/connector/shift4/transformers.rs index 1137fa58e8..372f110ab8 100644 --- a/crates/router/src/connector/shift4/transformers.rs +++ b/crates/router/src/connector/shift4/transformers.rs @@ -299,9 +299,8 @@ impl number: card.card_number.clone(), exp_month: card.card_exp_month.clone(), exp_year: card.card_exp_year.clone(), - cardholder_name: card - .card_holder_name - .clone() + cardholder_name: item + .get_optional_billing_full_name() .unwrap_or(Secret::new("".to_string())), }; if item.is_three_ds() { diff --git a/crates/router/src/connector/stax/transformers.rs b/crates/router/src/connector/stax/transformers.rs index b8ba6416a0..ae65b40940 100644 --- a/crates/router/src/connector/stax/transformers.rs +++ b/crates/router/src/connector/stax/transformers.rs @@ -229,8 +229,8 @@ impl TryFrom<&types::TokenizationRouterData> for StaxTokenRequest { let stax_card_data = StaxTokenizeData { card_exp: card_data .get_card_expiry_month_year_2_digit_with_delimiter("".to_string())?, - person_name: card_data - .card_holder_name + person_name: item + .get_optional_billing_full_name() .unwrap_or(Secret::new("".to_string())), card_number: card_data.card_number, card_cvv: card_data.card_cvc, diff --git a/crates/router/src/connector/threedsecureio/transformers.rs b/crates/router/src/connector/threedsecureio/transformers.rs index f119be9ccf..04a2399b3b 100644 --- a/crates/router/src/connector/threedsecureio/transformers.rs +++ b/crates/router/src/connector/threedsecureio/transformers.rs @@ -328,6 +328,9 @@ impl TryFrom<&ThreedsecureioRouterData<&types::authentication::ConnectorAuthenti })?; let meta: ThreeDSecureIoConnectorMetaData = to_connector_meta(request.pre_authentication_data.connector_metadata.clone())?; + + let card_holder_name = billing_address.get_optional_full_name(); + Ok(Self { ds_start_protocol_version: meta.ds_start_protocol_version.clone(), ds_end_protocol_version: meta.ds_end_protocol_version.clone(), @@ -452,7 +455,7 @@ impl TryFrom<&ThreedsecureioRouterData<&types::authentication::ConnectorAuthenti }), DeviceChannel::Browser => None, }, - cardholder_name: card_details.card_holder_name, + cardholder_name: card_holder_name, email: request.email.clone(), }) } diff --git a/crates/router/src/connector/utils.rs b/crates/router/src/connector/utils.rs index b0c0fe8e68..7d5afacd3f 100644 --- a/crates/router/src/connector/utils.rs +++ b/crates/router/src/connector/utils.rs @@ -88,6 +88,8 @@ pub trait RouterData { fn get_optional_billing(&self) -> Option<&api::Address>; fn get_optional_shipping(&self) -> Option<&api::Address>; + + fn get_optional_billing_full_name(&self) -> Option>; fn get_optional_billing_line1(&self) -> Option>; fn get_optional_billing_line2(&self) -> Option>; fn get_optional_billing_city(&self) -> Option; @@ -353,6 +355,12 @@ impl RouterData for types::RouterData Option> { + self.get_optional_billing() + .and_then(|billing_details| billing_details.address.as_ref()) + .and_then(|billing_address| billing_address.get_optional_full_name()) + } + #[cfg(feature = "payouts")] fn get_payout_method_data(&self) -> Result { self.payout_method_data diff --git a/crates/router/src/connector/worldline/transformers.rs b/crates/router/src/connector/worldline/transformers.rs index 490c499404..3dba5ea24e 100644 --- a/crates/router/src/connector/worldline/transformers.rs +++ b/crates/router/src/connector/worldline/transformers.rs @@ -236,35 +236,36 @@ impl >, >, ) -> Result { - let payment_data = match &item.router_data.request.payment_method_data { - domain::PaymentMethodData::Card(card) => { - WorldlinePaymentMethod::CardPaymentMethodSpecificInput(Box::new(make_card_request( - &item.router_data.request, - card, - )?)) - } - domain::PaymentMethodData::BankRedirect(bank_redirect) => { - WorldlinePaymentMethod::RedirectPaymentMethodSpecificInput(Box::new( - make_bank_redirect_request(&item.router_data.request, bank_redirect)?, - )) - } - domain::PaymentMethodData::CardRedirect(_) - | domain::PaymentMethodData::Wallet(_) - | domain::PaymentMethodData::PayLater(_) - | domain::PaymentMethodData::BankDebit(_) - | 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("worldline"), - ))? - } - }; + let payment_data = + match &item.router_data.request.payment_method_data { + domain::PaymentMethodData::Card(card) => { + let card_holder_name = item.router_data.get_optional_billing_full_name(); + WorldlinePaymentMethod::CardPaymentMethodSpecificInput(Box::new( + make_card_request(&item.router_data.request, card, card_holder_name)?, + )) + } + domain::PaymentMethodData::BankRedirect(bank_redirect) => { + WorldlinePaymentMethod::RedirectPaymentMethodSpecificInput(Box::new( + make_bank_redirect_request(&item.router_data.request, bank_redirect)?, + )) + } + domain::PaymentMethodData::CardRedirect(_) + | domain::PaymentMethodData::Wallet(_) + | domain::PaymentMethodData::PayLater(_) + | domain::PaymentMethodData::BankDebit(_) + | 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("worldline"), + ))? + } + }; let billing_address = item.router_data.get_billing()?; @@ -343,6 +344,7 @@ impl TryFrom<&common_enums::enums::BankNames> for WorldlineBic { fn make_card_request( req: &PaymentsAuthorizeData, ccard: &domain::Card, + card_holder_name: Option>, ) -> Result> { let expiry_year = ccard.card_exp_year.peek(); let secret_value = format!( @@ -355,10 +357,7 @@ fn make_card_request( let expiry_date: Secret = Secret::new(secret_value); let card = Card { card_number: ccard.card_number.clone(), - cardholder_name: ccard - .card_holder_name - .clone() - .unwrap_or(Secret::new("".to_string())), + cardholder_name: card_holder_name.unwrap_or(Secret::new("".to_string())), cvv: ccard.card_cvc.clone(), expiry_date, }; diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs index 91b1d7f319..e0950a7289 100644 --- a/crates/router/src/core/payments.rs +++ b/crates/router/src/core/payments.rs @@ -2210,6 +2210,7 @@ pub mod payment_address { self.unified_payment_method_billing.as_ref() } + /// Unify the billing details from `payment_method_data.[payment_method_data].billing details`. pub fn unify_with_payment_method_data_billing( self, payment_method_data_billing: Option, diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index 9ec570b441..624e5e7fea 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -1208,6 +1208,7 @@ pub(crate) async fn get_payment_method_create_request( payment_method: Option, payment_method_type: Option, customer: &domain::Customer, + billing_name: Option>, ) -> RouterResult { match payment_method_data { Some(pm_data) => match payment_method { @@ -1217,7 +1218,7 @@ pub(crate) async fn get_payment_method_create_request( card_number: card.card_number.clone(), card_exp_month: card.card_exp_month.clone(), card_exp_year: card.card_exp_year.clone(), - card_holder_name: card.card_holder_name.clone(), + card_holder_name: billing_name, nick_name: card.nick_name.clone(), card_issuing_country: card.card_issuing_country.clone(), card_network: card.card_network.clone(), diff --git a/crates/router/src/core/payments/tokenization.rs b/crates/router/src/core/payments/tokenization.rs index 3f24c55c99..b199286f61 100644 --- a/crates/router/src/core/payments/tokenization.rs +++ b/crates/router/src/core/payments/tokenization.rs @@ -164,11 +164,18 @@ where let pm_id = if customer_acceptance.is_some() { let customer = maybe_customer.to_owned().get_required_value("customer")?; + let billing_name = resp + .address + .get_payment_method_billing() + .and_then(|billing_details| billing_details.address.as_ref()) + .and_then(|address| address.get_optional_full_name()); + let payment_method_create_request = helpers::get_payment_method_create_request( Some(&resp.request.get_payment_method_data()), Some(resp.payment_method), payment_method_type, &customer, + billing_name, ) .await?; let merchant_id = &merchant_account.merchant_id; @@ -537,7 +544,7 @@ async fn skip_saving_card_in_locker( let card_isin = payment_method_request .card .clone() - .map(|c: api_models::payment_methods::CardDetail| c.card_number.get_card_isin()); + .map(|c| c.card_number.get_card_isin()); match payment_method_request.card.clone() { Some(card) => { diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index 595ca3f94a..cc319e3912 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -53,7 +53,7 @@ where Err(errors::ApiErrorResponse::MerchantConnectorAccountDisabled) })?; - let test_mode: Option = merchant_connector_account.is_test_mode_on(); + let test_mode = merchant_connector_account.is_test_mode_on(); let auth_type: types::ConnectorAuthType = merchant_connector_account .get_connector_account_details() diff --git a/crates/router/src/types/domain/payments.rs b/crates/router/src/types/domain/payments.rs index b8285fbdc9..61a036d107 100644 --- a/crates/router/src/types/domain/payments.rs +++ b/crates/router/src/types/domain/payments.rs @@ -48,7 +48,6 @@ pub struct Card { pub card_number: cards::CardNumber, pub card_exp_month: Secret, pub card_exp_year: Secret, - pub card_holder_name: Option>, pub card_cvc: Secret, pub card_issuer: Option, pub card_network: Option, @@ -368,7 +367,7 @@ impl From for Card { card_number, card_exp_month, card_exp_year, - card_holder_name, + card_holder_name: _, card_cvc, card_issuer, card_network, @@ -382,7 +381,6 @@ impl From for Card { card_number, card_exp_month, card_exp_year, - card_holder_name, card_cvc, card_issuer, card_network, diff --git a/crates/router/src/utils/verify_connector.rs b/crates/router/src/utils/verify_connector.rs index 0d1deeaaed..617cb415ee 100644 --- a/crates/router/src/utils/verify_connector.rs +++ b/crates/router/src/utils/verify_connector.rs @@ -19,7 +19,6 @@ pub fn generate_card_from_details( card_network: None, card_exp_year: masking::Secret::new(card_exp_year), card_exp_month: masking::Secret::new(card_exp_month), - card_holder_name: Some(masking::Secret::new("HyperSwitch".to_string())), nick_name: None, card_type: None, card_issuing_country: None, diff --git a/crates/router/tests/connectors/aci.rs b/crates/router/tests/connectors/aci.rs index 6cf8fe9994..52f86f67b3 100644 --- a/crates/router/tests/connectors/aci.rs +++ b/crates/router/tests/connectors/aci.rs @@ -1,5 +1,6 @@ use std::{marker::PhantomData, str::FromStr}; +use api_models::payments::{Address, AddressDetails}; use masking::Secret; use router::{ configs::settings::Settings, @@ -40,7 +41,6 @@ fn construct_payment_router_data() -> types::PaymentsAuthorizeRouterData { card_number: cards::CardNumber::from_str("4200000000000000").unwrap(), card_exp_month: Secret::new("10".to_string()), card_exp_year: Secret::new("2025".to_string()), - card_holder_name: Some(masking::Secret::new("John Doe".to_string())), card_cvc: Secret::new("999".to_string()), card_issuer: None, card_network: None, @@ -78,7 +78,19 @@ fn construct_payment_router_data() -> types::PaymentsAuthorizeRouterData { customer_acceptance: None, }, response: Err(types::ErrorResponse::default()), - address: PaymentAddress::default(), + address: PaymentAddress::new( + None, + None, + Some(Address { + address: Some(AddressDetails { + first_name: Some(Secret::new("John".to_string())), + last_name: Some(Secret::new("Doe".to_string())), + ..Default::default() + }), + phone: None, + email: None, + }), + ), connector_meta_data: None, amount_captured: None, access_token: None, @@ -244,7 +256,6 @@ async fn payments_create_failure() { card_number: cards::CardNumber::from_str("4200000000000000").unwrap(), card_exp_month: Secret::new("10".to_string()), card_exp_year: Secret::new("2025".to_string()), - card_holder_name: Some(masking::Secret::new("John Doe".to_string())), card_cvc: Secret::new("99".to_string()), card_issuer: None, card_network: None, diff --git a/crates/router/tests/connectors/adyen.rs b/crates/router/tests/connectors/adyen.rs index 3ae8c78234..b404f14ed3 100644 --- a/crates/router/tests/connectors/adyen.rs +++ b/crates/router/tests/connectors/adyen.rs @@ -61,7 +61,9 @@ impl AdyenTest { zip: Some(Secret::new("94122".to_string())), line1: Some(Secret::new("1467".to_string())), line2: Some(Secret::new("Harrison Street".to_string())), - ..Default::default() + line3: None, + first_name: Some(Secret::new("John".to_string())), + last_name: Some(Secret::new("Dough".to_string())), }), phone: None, email: None, @@ -138,7 +140,6 @@ impl AdyenTest { card_number: cards::CardNumber::from_str(card_number).unwrap(), card_exp_month: Secret::new(card_exp_month.to_string()), card_exp_year: Secret::new(card_exp_year.to_string()), - card_holder_name: Some(masking::Secret::new("John Doe".to_string())), card_cvc: Secret::new(card_cvc.to_string()), card_issuer: None, card_network: None, diff --git a/crates/router/tests/connectors/airwallex.rs b/crates/router/tests/connectors/airwallex.rs index 66f8a42a47..95b07162ac 100644 --- a/crates/router/tests/connectors/airwallex.rs +++ b/crates/router/tests/connectors/airwallex.rs @@ -1,5 +1,6 @@ use std::str::FromStr; +use api_models::payments::{Address, AddressDetails}; use masking::{PeekInterface, Secret}; use router::types::{self, domain, storage::enums, AccessToken}; @@ -51,6 +52,19 @@ fn get_access_token() -> Option { fn get_default_payment_info() -> Option { Some(utils::PaymentInfo { access_token: get_access_token(), + address: Some(types::PaymentAddress::new( + None, + None, + Some(Address { + address: Some(AddressDetails { + first_name: Some(Secret::new("John".to_string())), + last_name: Some(Secret::new("Doe".to_string())), + ..Default::default() + }), + phone: None, + email: None, + }), + )), ..Default::default() }) } @@ -60,7 +74,6 @@ fn payment_method_details() -> Option { card_number: cards::CardNumber::from_str("4035501000000008").unwrap(), card_exp_month: Secret::new("02".to_string()), card_exp_year: Secret::new("2035".to_string()), - card_holder_name: Some(masking::Secret::new("John Doe".to_string())), card_cvc: Secret::new("123".to_string()), card_issuer: None, card_network: None, diff --git a/crates/router/tests/connectors/authorizedotnet.rs b/crates/router/tests/connectors/authorizedotnet.rs index 0020653916..2b9a79b0b7 100644 --- a/crates/router/tests/connectors/authorizedotnet.rs +++ b/crates/router/tests/connectors/authorizedotnet.rs @@ -5,7 +5,7 @@ use router::types::{self, domain, storage::enums}; use crate::{ connector_auth, - utils::{self, ConnectorActions}, + utils::{self, ConnectorActions, PaymentInfo}, }; #[derive(Clone, Copy)] @@ -42,7 +42,6 @@ fn get_payment_method_data() -> domain::Card { card_number: cards::CardNumber::from_str("5424000000000015").unwrap(), card_exp_month: Secret::new("02".to_string()), card_exp_year: Secret::new("2035".to_string()), - card_holder_name: Some(masking::Secret::new("John Doe".to_string())), card_cvc: Secret::new("123".to_string()), ..Default::default() } @@ -62,7 +61,7 @@ async fn should_only_authorize_payment() { capture_method: Some(diesel_models::enums::CaptureMethod::Manual), ..utils::PaymentAuthorizeType::default().0 }), - None, + Some(PaymentInfo::with_default_billing_name()), ) .await .expect("Authorize payment response"); @@ -99,7 +98,7 @@ async fn should_capture_authorized_payment() { capture_method: Some(diesel_models::enums::CaptureMethod::Manual), ..utils::PaymentAuthorizeType::default().0 }), - None, + Some(PaymentInfo::with_default_billing_name()), ) .await .expect("Authorize payment response"); @@ -163,7 +162,7 @@ async fn should_partially_capture_authorized_payment() { capture_method: Some(diesel_models::enums::CaptureMethod::Manual), ..utils::PaymentAuthorizeType::default().0 }), - None, + Some(PaymentInfo::with_default_billing_name()), ) .await .expect("Authorize payment response"); @@ -227,7 +226,7 @@ async fn should_sync_authorized_payment() { capture_method: Some(diesel_models::enums::CaptureMethod::Manual), ..utils::PaymentAuthorizeType::default().0 }), - None, + Some(PaymentInfo::with_default_billing_name()), ) .await .expect("Authorize payment response"); @@ -263,7 +262,7 @@ async fn should_void_authorized_payment() { capture_method: Some(diesel_models::enums::CaptureMethod::Manual), ..utils::PaymentAuthorizeType::default().0 }), - None, + Some(PaymentInfo::with_default_billing_name()), ) .await .expect("Authorize payment response"); diff --git a/crates/router/tests/connectors/bluesnap.rs b/crates/router/tests/connectors/bluesnap.rs index 475953ce15..2e02f25934 100644 --- a/crates/router/tests/connectors/bluesnap.rs +++ b/crates/router/tests/connectors/bluesnap.rs @@ -402,7 +402,6 @@ async fn should_fail_payment_for_incorrect_cvc() { Some(types::PaymentsAuthorizeData { email: Some(Email::from_str("test@gmail.com").unwrap()), payment_method_data: types::domain::PaymentMethodData::Card(domain::Card { - card_holder_name: Some(masking::Secret::new("John Doe".to_string())), card_cvc: Secret::new("12345".to_string()), ..utils::CCardType::default().0 }), @@ -428,7 +427,6 @@ async fn should_fail_payment_for_invalid_exp_month() { Some(types::PaymentsAuthorizeData { email: Some(Email::from_str("test@gmail.com").unwrap()), payment_method_data: types::domain::PaymentMethodData::Card(domain::Card { - card_holder_name: Some(masking::Secret::new("John Doe".to_string())), card_exp_month: Secret::new("20".to_string()), ..utils::CCardType::default().0 }), @@ -454,7 +452,6 @@ async fn should_fail_payment_for_incorrect_expiry_year() { Some(types::PaymentsAuthorizeData { email: Some(Email::from_str("test@gmail.com").unwrap()), payment_method_data: types::domain::PaymentMethodData::Card(domain::Card { - card_holder_name: Some(masking::Secret::new("John Doe".to_string())), card_exp_year: Secret::new("2000".to_string()), ..utils::CCardType::default().0 }), diff --git a/crates/router/tests/connectors/fiserv.rs b/crates/router/tests/connectors/fiserv.rs index 5e484e5d77..050d6a5406 100644 --- a/crates/router/tests/connectors/fiserv.rs +++ b/crates/router/tests/connectors/fiserv.rs @@ -46,7 +46,6 @@ fn payment_method_details() -> Option { card_number: cards::CardNumber::from_str("4005550000000019").unwrap(), card_exp_month: Secret::new("02".to_string()), card_exp_year: Secret::new("2035".to_string()), - card_holder_name: Some(masking::Secret::new("John Doe".to_string())), card_cvc: Secret::new("123".to_string()), card_issuer: None, card_network: None, @@ -63,7 +62,7 @@ fn payment_method_details() -> Option { fn get_default_payment_info() -> Option { Some(utils::PaymentInfo { connector_meta_data: Some(json!({"terminalId": "10000001"})), - ..Default::default() + ..utils::PaymentInfo::with_default_billing_name() }) } diff --git a/crates/router/tests/connectors/payme.rs b/crates/router/tests/connectors/payme.rs index cda6f22e15..5e9531a4f7 100644 --- a/crates/router/tests/connectors/payme.rs +++ b/crates/router/tests/connectors/payme.rs @@ -95,7 +95,6 @@ fn payment_method_details() -> Option { card_cvc: Secret::new("123".to_string()), card_exp_month: Secret::new("10".to_string()), card_exp_year: Secret::new("2025".to_string()), - card_holder_name: Some(masking::Secret::new("John Doe".to_string())), ..utils::CCardType::default().0 }), amount: 1000, diff --git a/crates/router/tests/connectors/rapyd.rs b/crates/router/tests/connectors/rapyd.rs index 5cfb8900ec..61bc7ccdf1 100644 --- a/crates/router/tests/connectors/rapyd.rs +++ b/crates/router/tests/connectors/rapyd.rs @@ -7,7 +7,7 @@ use serial_test::serial; use crate::{ connector_auth, - utils::{self, ConnectorActions}, + utils::{self, ConnectorActions, PaymentInfo}, }; struct Rapyd; @@ -46,7 +46,6 @@ async fn should_only_authorize_payment() { card_number: cards::CardNumber::from_str("4111111111111111").unwrap(), card_exp_month: Secret::new("02".to_string()), card_exp_year: Secret::new("2024".to_string()), - card_holder_name: Some(masking::Secret::new("John Doe".to_string())), card_cvc: Secret::new("123".to_string()), card_issuer: None, card_network: None, @@ -58,7 +57,7 @@ async fn should_only_authorize_payment() { capture_method: Some(diesel_models::enums::CaptureMethod::Manual), ..utils::PaymentAuthorizeType::default().0 }), - None, + Some(PaymentInfo::with_default_billing_name()), ) .await .unwrap(); @@ -74,7 +73,6 @@ async fn should_authorize_and_capture_payment() { card_number: cards::CardNumber::from_str("4111111111111111").unwrap(), card_exp_month: Secret::new("02".to_string()), card_exp_year: Secret::new("2024".to_string()), - card_holder_name: Some(masking::Secret::new("John Doe".to_string())), card_cvc: Secret::new("123".to_string()), card_issuer: None, card_network: None, @@ -85,7 +83,7 @@ async fn should_authorize_and_capture_payment() { }), ..utils::PaymentAuthorizeType::default().0 }), - None, + Some(PaymentInfo::with_default_billing_name()), ) .await .unwrap(); @@ -95,7 +93,10 @@ async fn should_authorize_and_capture_payment() { #[actix_web::test] async fn should_capture_already_authorized_payment() { let connector = Rapyd {}; - let authorize_response = connector.authorize_payment(None, None).await.unwrap(); + let authorize_response = connector + .authorize_payment(None, Some(PaymentInfo::with_default_billing_name())) + .await + .unwrap(); assert_eq!(authorize_response.status, enums::AttemptStatus::Authorized); let txn_id = utils::get_connector_transaction_id(authorize_response.response); let response: OptionFuture<_> = txn_id @@ -114,7 +115,10 @@ async fn should_capture_already_authorized_payment() { #[serial] async fn voiding_already_authorized_payment_fails() { let connector = Rapyd {}; - let authorize_response = connector.authorize_payment(None, None).await.unwrap(); + let authorize_response = connector + .authorize_payment(None, Some(PaymentInfo::with_default_billing_name())) + .await + .unwrap(); assert_eq!(authorize_response.status, enums::AttemptStatus::Authorized); let txn_id = utils::get_connector_transaction_id(authorize_response.response); let response: OptionFuture<_> = txn_id diff --git a/crates/router/tests/connectors/utils.rs b/crates/router/tests/connectors/utils.rs index 641253a561..47ec71cc94 100644 --- a/crates/router/tests/connectors/utils.rs +++ b/crates/router/tests/connectors/utils.rs @@ -54,6 +54,27 @@ pub struct PaymentInfo { pub country: Option, } +impl PaymentInfo { + pub fn with_default_billing_name() -> Self { + Self { + address: Some(types::PaymentAddress::new( + None, + None, + Some(types::api::Address { + address: Some(types::api::AddressDetails { + first_name: Some(Secret::new("John".to_string())), + last_name: Some(Secret::new("Doe".to_string())), + ..Default::default() + }), + phone: None, + email: None, + }), + )), + ..Default::default() + } + } +} + #[async_trait] pub trait ConnectorActions: Connector { /// For initiating payments when `CaptureMethod` is set to `Manual` @@ -875,7 +896,6 @@ impl Default for CCardType { card_number: cards::CardNumber::from_str("4200000000000000").unwrap(), card_exp_month: Secret::new("10".to_string()), card_exp_year: Secret::new("2025".to_string()), - card_holder_name: Some(masking::Secret::new("John Doe".to_string())), card_cvc: Secret::new("999".to_string()), card_issuer: None, card_network: None, diff --git a/crates/router/tests/connectors/worldline.rs b/crates/router/tests/connectors/worldline.rs index ea26c6c609..21a5a57412 100644 --- a/crates/router/tests/connectors/worldline.rs +++ b/crates/router/tests/connectors/worldline.rs @@ -48,6 +48,8 @@ impl WorldlineTest { Some(Address { address: Some(AddressDetails { country: Some(api_models::enums::CountryAlpha2::US), + first_name: Some(Secret::new(String::from("John"))), + last_name: Some(Secret::new(String::from("Dough"))), ..Default::default() }), phone: None, @@ -73,7 +75,6 @@ impl WorldlineTest { card_number: cards::CardNumber::from_str(card_number).unwrap(), card_exp_month: Secret::new(card_exp_month.to_string()), card_exp_year: Secret::new(card_exp_year.to_string()), - card_holder_name: Some(masking::Secret::new("John Doe".to_string())), card_cvc: Secret::new(card_cvc.to_string()), card_issuer: None, card_network: None,