From 1100dcc6053990cf832c00cf29db700d77f78480 Mon Sep 17 00:00:00 2001 From: Sakil Mostak <73734619+Sakilmostak@users.noreply.github.com> Date: Tue, 1 Apr 2025 14:58:54 +0530 Subject: [PATCH] feat(core): implement `NameType` for name validation (#6734) --- crates/api_models/src/customers.rs | 2 +- crates/api_models/src/mandates.rs | 8 +- crates/api_models/src/payment_methods.rs | 71 +++---- crates/api_models/src/payments.rs | 105 +++++---- .../src/payments/additional_info.rs | 14 +- crates/api_models/src/payouts.rs | 2 +- crates/cards/tests/basic.rs | 4 +- crates/common_utils/src/types.rs | 201 +++++++++++++++++- .../src/connectors/adyen/transformers.rs | 6 +- .../authorizedotnet/transformers.rs | 12 +- .../connectors/bankofamerica/transformers.rs | 4 +- .../src/connectors/bluesnap/transformers.rs | 4 +- .../connectors/cybersource/transformers.rs | 5 +- .../src/connectors/dlocal/transformers.rs | 6 +- .../src/connectors/nuvei/transformers.rs | 6 +- .../src/connectors/paypal/transformers.rs | 4 +- .../src/connectors/trustpay/transformers.rs | 6 +- .../src/connectors/wellsfargo/transformers.rs | 4 +- .../src/connectors/worldline/transformers.rs | 6 +- crates/hyperswitch_connectors/src/utils.rs | 43 ++-- .../hyperswitch_domain_models/src/address.rs | 14 +- .../src/bulk_tokenization.rs | 12 +- .../src/payment_method_data.rs | 36 ++-- .../src/router_data.rs | 2 +- .../src/router_request_types/fraud_check.rs | 2 +- .../compatibility/stripe/customers/types.rs | 2 +- .../stripe/payment_intents/types.rs | 8 +- .../stripe/setup_intents/types.rs | 4 +- .../connector/netcetera/netcetera_types.rs | 10 +- .../src/connector/payone/transformers.rs | 1 + .../connector/riskified/transformers/api.rs | 8 +- .../connector/signifyd/transformers/api.rs | 2 +- .../src/connector/stripe/transformers.rs | 8 +- .../connector/stripe/transformers/connect.rs | 4 +- crates/router/src/connector/utils.rs | 27 +-- crates/router/src/core/customers.rs | 2 +- crates/router/src/core/locker_migration.rs | 2 +- crates/router/src/core/payment_methods.rs | 3 +- .../router/src/core/payment_methods/cards.rs | 46 ++-- .../payment_methods/network_tokenization.rs | 4 +- .../src/core/payment_methods/tokenize.rs | 12 +- .../payment_methods/tokenize/card_executor.rs | 5 +- .../tokenize/payment_method_executor.rs | 5 +- .../src/core/payment_methods/transformers.rs | 12 +- .../router/src/core/payment_methods/vault.rs | 8 +- crates/router/src/core/payments/helpers.rs | 24 ++- crates/router/src/core/payouts/helpers.rs | 4 +- .../core/unified_authentication_service.rs | 2 +- crates/router/src/core/utils.rs | 16 +- crates/router/src/types/api/payments.rs | 8 +- crates/router/src/types/transformers.rs | 42 +++- crates/router/src/utils.rs | 16 +- crates/router/tests/connectors/aci.rs | 24 ++- crates/router/tests/connectors/adyen.rs | 20 +- crates/router/tests/connectors/airwallex.rs | 15 +- crates/router/tests/connectors/bitpay.rs | 8 +- crates/router/tests/connectors/bluesnap.rs | 8 +- crates/router/tests/connectors/coinbase.rs | 8 +- crates/router/tests/connectors/cryptopay.rs | 8 +- crates/router/tests/connectors/cybersource.rs | 8 +- crates/router/tests/connectors/fiserv.rs | 8 +- crates/router/tests/connectors/forte.rs | 8 +- crates/router/tests/connectors/iatapay.rs | 8 +- .../router/tests/connectors/multisafepay.rs | 8 +- crates/router/tests/connectors/opennode.rs | 8 +- crates/router/tests/connectors/payme.rs | 8 +- crates/router/tests/connectors/rapyd.rs | 16 +- crates/router/tests/connectors/trustpay.rs | 8 +- crates/router/tests/connectors/utils.rs | 15 +- crates/router/tests/connectors/worldline.rs | 16 +- crates/router/tests/payments.rs | 16 +- crates/router/tests/payments2.rs | 16 +- 72 files changed, 734 insertions(+), 364 deletions(-) diff --git a/crates/api_models/src/customers.rs b/crates/api_models/src/customers.rs index eb61cae6e4..a6ffb55e61 100644 --- a/crates/api_models/src/customers.rs +++ b/crates/api_models/src/customers.rs @@ -18,7 +18,7 @@ pub struct CustomerRequest { pub merchant_id: id_type::MerchantId, /// The customer's name #[schema(max_length = 255, value_type = Option, example = "Jon Test")] - pub name: Option>, + pub name: Option, /// The customer's email address #[schema(value_type = Option, max_length = 255, example = "JonTest@test.com")] pub email: Option, diff --git a/crates/api_models/src/mandates.rs b/crates/api_models/src/mandates.rs index 2d61a63098..4c0b8d4d18 100644 --- a/crates/api_models/src/mandates.rs +++ b/crates/api_models/src/mandates.rs @@ -57,7 +57,7 @@ pub struct MandateCardDetails { pub card_exp_year: Option>, /// The card holder name #[schema(value_type = Option)] - pub card_holder_name: Option>, + pub card_holder_name: Option, /// The token from card locker #[schema(value_type = Option)] pub card_token: Option>, @@ -79,7 +79,7 @@ pub struct MandateCardDetails { pub card_type: Option, /// The nick_name of the card holder #[schema(value_type = Option)] - pub nick_name: Option>, + pub nick_name: Option, } #[derive(Clone, Debug, Deserialize, ToSchema, Serialize)] @@ -151,7 +151,7 @@ pub struct NetworkTransactionIdAndCardDetails { /// The card holder's name #[schema(value_type = String, example = "John Test")] - pub card_holder_name: Option>, + pub card_holder_name: Option, /// The name of the issuer of card #[schema(example = "chase")] @@ -172,7 +172,7 @@ pub struct NetworkTransactionIdAndCardDetails { /// The card holder's nick name #[schema(value_type = Option, example = "John Test")] - pub nick_name: Option>, + pub nick_name: Option, /// The network transaction ID provided by the card network during a CIT (Customer Initiated Transaction), /// where `setup_future_usage` is set to `off_session`. diff --git a/crates/api_models/src/payment_methods.rs b/crates/api_models/src/payment_methods.rs index 0a2d7dedd5..aca5dc677d 100644 --- a/crates/api_models/src/payment_methods.rs +++ b/crates/api_models/src/payment_methods.rs @@ -539,11 +539,11 @@ pub struct CardDetail { /// Card Holder Name #[schema(value_type = String,example = "John Doe")] - pub card_holder_name: Option>, + pub card_holder_name: Option, /// Card Holder's Nick Name #[schema(value_type = Option,example = "John Doe")] - pub nick_name: Option>, + pub nick_name: Option, /// Card Issuing Country pub card_issuing_country: Option, @@ -599,11 +599,11 @@ pub struct CardDetail { /// Card Holder Name #[schema(value_type = String,example = "John Doe")] - pub card_holder_name: Option>, + pub card_holder_name: Option, /// Card Holder's Nick Name #[schema(value_type = Option,example = "John Doe")] - pub nick_name: Option>, + pub nick_name: Option, /// Card Issuing Country #[schema(value_type = CountryAlpha2)] @@ -642,11 +642,11 @@ pub struct MigrateCardDetail { /// Card Holder Name #[schema(value_type = String,example = "John Doe")] - pub card_holder_name: Option>, + pub card_holder_name: Option, /// Card Holder's Nick Name #[schema(value_type = Option,example = "John Doe")] - pub nick_name: Option>, + pub nick_name: Option, /// Card Issuing Country pub card_issuing_country: Option, @@ -679,11 +679,11 @@ pub struct MigrateNetworkTokenData { /// Card Holder Name #[schema(value_type = String,example = "John Doe")] - pub card_holder_name: Option>, + pub card_holder_name: Option, /// Card Holder's Nick Name #[schema(value_type = Option,example = "John Doe")] - pub nick_name: Option>, + pub nick_name: Option, /// Card Issuing Country pub card_issuing_country: Option, @@ -726,11 +726,11 @@ pub struct CardDetailUpdate { /// Card Holder Name #[schema(value_type = String,example = "John Doe")] - pub card_holder_name: Option>, + pub card_holder_name: Option, /// Card Holder's Nick Name #[schema(value_type = Option,example = "John Doe")] - pub nick_name: Option>, + pub nick_name: Option, } #[cfg(all( @@ -753,10 +753,7 @@ impl CardDetailUpdate { .card_holder_name .clone() .or(card_data_from_locker.name_on_card), - nick_name: self - .nick_name - .clone() - .or(card_data_from_locker.nick_name.map(masking::Secret::new)), + nick_name: self.nick_name.clone().or(card_data_from_locker.nick_name), card_issuing_country: None, card_network: None, card_issuer: None, @@ -771,11 +768,11 @@ impl CardDetailUpdate { pub struct CardDetailUpdate { /// Card Holder Name #[schema(value_type = String,example = "John Doe")] - pub card_holder_name: Option>, + pub card_holder_name: Option, /// Card Holder's Nick Name #[schema(value_type = Option,example = "John Doe")] - pub nick_name: Option>, + pub nick_name: Option, } #[cfg(all(feature = "v2", feature = "payment_methods_v2"))] @@ -789,10 +786,7 @@ impl CardDetailUpdate { .card_holder_name .clone() .or(card_data_from_locker.name_on_card), - nick_name: self - .nick_name - .clone() - .or(card_data_from_locker.nick_name.map(masking::Secret::new)), + nick_name: self.nick_name.clone().or(card_data_from_locker.nick_name), card_issuing_country: None, card_network: None, card_issuer: None, @@ -970,8 +964,8 @@ pub struct CardDetailsPaymentMethod { pub issuer_country: Option, pub expiry_month: Option>, pub expiry_year: Option>, - pub nick_name: Option>, - pub card_holder_name: Option>, + pub nick_name: Option, + pub card_holder_name: Option, pub card_isin: Option, pub card_issuer: Option, pub card_network: Option, @@ -1065,12 +1059,12 @@ pub enum BankAccountAccessCreds { #[derive(Debug, serde::Deserialize, serde::Serialize, Clone)] pub struct Card { pub card_number: CardNumber, - pub name_on_card: Option>, + pub name_on_card: Option, pub card_exp_month: masking::Secret, pub card_exp_year: masking::Secret, pub card_brand: Option, pub card_isin: Option, - pub nick_name: Option, + pub nick_name: Option, } #[cfg(all( @@ -1096,13 +1090,13 @@ pub struct CardDetailFromLocker { pub card_token: Option>, #[schema(value_type=Option)] - pub card_holder_name: Option>, + pub card_holder_name: Option, #[schema(value_type=Option)] pub card_fingerprint: Option>, #[schema(value_type=Option)] - pub nick_name: Option>, + pub nick_name: Option, #[schema(value_type = Option)] pub card_network: Option, @@ -1130,13 +1124,13 @@ pub struct CardDetailFromLocker { pub expiry_year: Option>, #[schema(value_type=Option)] - pub card_holder_name: Option>, + pub card_holder_name: Option, #[schema(value_type=Option)] pub card_fingerprint: Option>, #[schema(value_type=Option)] - pub nick_name: Option>, + pub nick_name: Option, #[schema(value_type = Option)] pub card_network: Option, @@ -2291,8 +2285,8 @@ pub struct TokenizedCardValue1 { pub card_number: String, pub exp_year: String, pub exp_month: String, - pub name_on_card: Option, - pub nickname: Option, + pub name_on_card: Option, + pub nickname: Option, pub card_last_four: Option, pub card_token: Option, } @@ -2360,14 +2354,14 @@ pub struct TokenizedBankRedirectValue2 { #[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] pub struct PaymentMethodRecord { pub customer_id: id_type::CustomerId, - pub name: Option>, + pub name: Option, pub email: Option, pub phone: Option>, pub phone_country_code: Option, pub merchant_id: Option, pub payment_method: Option, pub payment_method_type: Option, - pub nick_name: masking::Secret, + pub nick_name: common_utils::types::NameType, pub payment_instrument_id: Option>, pub card_number_masked: masking::Secret, pub card_expiry_month: masking::Secret, @@ -2376,8 +2370,8 @@ pub struct PaymentMethodRecord { pub original_transaction_id: Option, pub billing_address_zip: masking::Secret, pub billing_address_state: masking::Secret, - pub billing_address_first_name: masking::Secret, - pub billing_address_last_name: masking::Secret, + pub billing_address_first_name: common_utils::types::NameType, + pub billing_address_last_name: common_utils::types::NameType, pub billing_address_city: String, pub billing_address_country: Option, pub billing_address_line1: masking::Secret, @@ -2647,11 +2641,11 @@ pub struct TokenizeCardRequest { /// Card Holder Name #[schema(value_type = Option, example = "John Doe")] - pub card_holder_name: Option>, + pub card_holder_name: Option, /// Card Holder's Nick Name #[schema(value_type = Option, example = "John Doe")] - pub nick_name: Option>, + pub nick_name: Option, /// Card Issuing Country pub card_issuing_country: Option, @@ -2712,10 +2706,7 @@ impl From<&Card> for MigrateCardDetail { card_exp_month: card.card_exp_month.clone(), card_exp_year: card.card_exp_year.clone(), card_holder_name: card.name_on_card.clone(), - nick_name: card - .nick_name - .as_ref() - .map(|name| masking::Secret::new(name.clone())), + nick_name: card.nick_name.clone(), card_issuing_country: None, card_network: None, card_issuer: None, diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index dd3c2aa124..817c5404da 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -23,7 +23,7 @@ use common_utils::{ types::{MinorUnit, StringMajorUnit}, }; use error_stack::ResultExt; -use masking::{PeekInterface, Secret, WithType}; +use masking::{Secret, WithType}; use router_derive::Setter; use serde::{de, ser::Serializer, Deserialize, Deserializer, Serialize}; use strum::Display; @@ -1913,7 +1913,7 @@ pub struct Card { /// The card holder's name #[schema(value_type = String, example = "John Test")] - pub card_holder_name: Option>, + pub card_holder_name: Option, /// The CVC number for the card #[schema(value_type = String, example = "242")] @@ -1937,7 +1937,7 @@ pub struct Card { pub bank_code: Option, /// The card holder's nick name #[schema(value_type = Option, example = "John Test")] - pub nick_name: Option>, + pub nick_name: Option, } #[cfg(feature = "v2")] @@ -1993,7 +1993,7 @@ pub struct ExtendedCardInfo { /// The card holder's name #[schema(value_type = String, example = "John Test")] - pub card_holder_name: Option>, + pub card_holder_name: Option, /// The CVC number for the card #[schema(value_type = String, example = "242")] @@ -2046,19 +2046,20 @@ impl GetAddressFromPaymentMethodData for Card { // John Wheat Dough // first_name -> John // last_name -> Wheat Dough - card_holder_name.peek().split_whitespace() + card_holder_name.split_whitespace() }) .map(|mut card_holder_name_iter| { let first_name = card_holder_name_iter .next() .map(ToOwned::to_owned) - .map(Secret::new); + .map(common_utils::types::NameType::get_unchecked); // it is unchecked because the string is coming from a checked type 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)) + Some(common_utils::types::NameType::get_unchecked(last_name)) + // it is unchecked because the string is coming from a checked type }; AddressDetails { @@ -2110,7 +2111,7 @@ impl Card { pub struct CardToken { /// The card holder's name #[schema(value_type = String, example = "John Test")] - pub card_holder_name: Option>, + pub card_holder_name: Option, /// The CVC number for the card #[schema(value_type = Option)] @@ -2152,7 +2153,7 @@ pub enum PayLaterData { billing_email: Option, /// The billing name #[schema(value_type = Option)] - billing_name: Option>, + billing_name: Option, }, /// For PayBright Redirect as PayLater Option PayBrightRedirect {}, @@ -2221,10 +2222,10 @@ pub enum BankDebitData { routing_number: Secret, #[schema(value_type = String, example = "John Test")] - card_holder_name: Option>, + card_holder_name: Option, #[schema(value_type = String, example = "John Doe")] - bank_account_holder_name: Option>, + bank_account_holder_name: Option, #[schema(value_type = String, example = "ACH")] bank_name: Option, @@ -2243,7 +2244,7 @@ pub enum BankDebitData { iban: Secret, /// Owner name for bank debit #[schema(value_type = String, example = "A. Schneider")] - bank_account_holder_name: Option>, + bank_account_holder_name: Option, }, BecsBankDebit { /// Billing details for bank debit @@ -2256,7 +2257,7 @@ pub enum BankDebitData { bsb_number: Secret, /// Owner name for bank debit #[schema(value_type = Option, example = "A. Schneider")] - bank_account_holder_name: Option>, + bank_account_holder_name: Option, }, BacsBankDebit { /// Billing details for bank debit @@ -2269,7 +2270,7 @@ pub enum BankDebitData { sort_code: Secret, /// holder name for bank debit #[schema(value_type = String, example = "A. Schneider")] - bank_account_holder_name: Option>, + bank_account_holder_name: Option, }, } @@ -2277,7 +2278,7 @@ impl GetAddressFromPaymentMethodData for BankDebitData { fn get_billing_address(&self) -> Option
{ fn get_billing_address_inner( bank_debit_billing: Option<&BankDebitBilling>, - bank_account_holder_name: Option<&Secret>, + bank_account_holder_name: Option<&common_utils::types::NameType>, ) -> Option
{ // We will always have address here let mut address = bank_debit_billing @@ -2404,8 +2405,10 @@ mod payment_method_data_serde { Some(billing_address_details), ) => { if card.card_holder_name.is_none() { - card.card_holder_name = - billing_address_details.get_optional_full_name(); + card.card_holder_name = billing_address_details + .get_optional_full_name() + .map(common_utils::types::NameType::get_unchecked_from_secret) + // it is unchecked because the string is coming from a checked type } Some(PaymentMethodData::Card(card.clone())) } @@ -2845,7 +2848,7 @@ pub struct AdditionalCardInfo { pub card_exp_year: Option>, - pub card_holder_name: Option>, + pub card_holder_name: Option, /// Additional payment checks done on the cvv and billing address by the processors. /// This is a free form field and the structure varies from processor to processor @@ -2943,7 +2946,7 @@ pub enum BankRedirectData { /// The card holder's name #[schema(value_type = String, example = "John Test")] - card_holder_name: Option>, + card_holder_name: Option, //Required by Stripes billing_details: Option, @@ -3194,10 +3197,10 @@ impl GetAddressFromPaymentMethodData for BankRedirectData { pub struct AlfamartVoucherData { /// The billing first name for Alfamart #[schema(value_type = Option, example = "Jane")] - pub first_name: Option>, + pub first_name: Option, /// The billing second name for Alfamart #[schema(value_type = Option, example = "Doe")] - pub last_name: Option>, + pub last_name: Option, /// The Email ID for Alfamart #[schema(value_type = Option, example = "example@me.com")] pub email: Option, @@ -3207,10 +3210,10 @@ pub struct AlfamartVoucherData { pub struct IndomaretVoucherData { /// The billing first name for Alfamart #[schema(value_type = Option, example = "Jane")] - pub first_name: Option>, + pub first_name: Option, /// The billing second name for Alfamart #[schema(value_type = Option, example = "Doe")] - pub last_name: Option>, + pub last_name: Option, /// The Email ID for Alfamart #[schema(value_type = Option, example = "example@me.com")] pub email: Option, @@ -3220,10 +3223,10 @@ pub struct IndomaretVoucherData { pub struct JCSVoucherData { /// The billing first name for Japanese convenience stores #[schema(value_type = Option, example = "Jane")] - pub first_name: Option>, + pub first_name: Option, /// The billing second name Japanese convenience stores #[schema(value_type = Option, example = "Doe")] - pub last_name: Option>, + pub last_name: Option, /// The Email ID for Japanese convenience stores #[schema(value_type = Option, example = "example@me.com")] pub email: Option, @@ -3243,10 +3246,10 @@ pub struct AchBillingDetails { pub struct DokuBillingDetails { /// The billing first name for Doku #[schema(value_type = Option, example = "Jane")] - pub first_name: Option>, + pub first_name: Option, /// The billing second name for Doku #[schema(value_type = Option, example = "Doe")] - pub last_name: Option>, + pub last_name: Option, /// The Email ID for Doku billing #[schema(value_type = Option, example = "example@me.com")] pub email: Option, @@ -3265,7 +3268,7 @@ pub struct SepaAndBacsBillingDetails { pub email: Option, /// The billing name for SEPA and BACS billing #[schema(value_type = Option, example = "Jane Doe")] - pub name: Option>, + pub name: Option, } #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize, ToSchema)] @@ -3303,7 +3306,7 @@ pub struct SofortBilling { pub struct BankRedirectBilling { /// The name for which billing is issued #[schema(value_type = String, example = "John Doe")] - pub billing_name: Option>, + pub billing_name: Option, /// The billing email for bank redirect #[schema(value_type = String, example = "example@example.com")] pub email: Option, @@ -3477,7 +3480,7 @@ impl GetAddressFromPaymentMethodData for BankTransferData { pub struct BankDebitBilling { /// The billing name for bank debits #[schema(value_type = Option, example = "John Doe")] - pub name: Option>, + pub name: Option, /// The billing email for bank debits #[schema(value_type = Option, example = "example@example.com")] pub email: Option, @@ -3907,7 +3910,7 @@ pub struct CardResponse { #[schema(value_type = Option)] pub card_exp_year: Option>, #[schema(value_type = Option)] - pub card_holder_name: Option>, + pub card_holder_name: Option, pub payment_checks: Option, pub authentication_data: Option, } @@ -4297,11 +4300,11 @@ pub struct AddressDetails { /// The first name for the address #[schema(value_type = Option, max_length = 255, example = "John")] - pub first_name: Option>, + pub first_name: Option, /// The last name for the address #[schema(value_type = Option, max_length = 255, example = "Doe")] - pub last_name: Option>, + pub last_name: Option, } impl AddressDetails { @@ -4309,10 +4312,10 @@ impl AddressDetails { 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() + String::from(first_name), + String::from(last_name) ))), - (Some(name), None) | (None, Some(name)) => Some(name.to_owned()), + (Some(name), None) | (None, Some(name)) => Some(Secret::from(name.to_owned())), _ => None, } } @@ -8298,7 +8301,6 @@ mod payments_response_api_contract { mod billing_from_payment_method_data { #![allow(clippy::unwrap_used)] use common_enums::CountryAlpha2; - use masking::ExposeOptionInterface; use super::*; @@ -8330,7 +8332,8 @@ mod billing_from_payment_method_data { #[test] fn test_bank_redirect_payment_method_data_eps() { let test_email = Email::try_from("example@example.com".to_string()).unwrap(); - let test_first_name = Secret::new(String::from("Chaser")); + let test_first_name = + common_utils::types::NameType::try_from(String::from("Chaser")).unwrap(); let bank_redirect_billing = BankRedirectBilling { billing_name: Some(test_first_name.clone()), @@ -8381,7 +8384,8 @@ mod billing_from_payment_method_data { #[test] fn test_bank_debit_payment_method_data_ach() { let test_email = Email::try_from("example@example.com".to_string()).unwrap(); - let test_first_name = Secret::new(String::from("Chaser")); + let test_first_name = + common_utils::types::NameType::try_from(String::from("Chaser")).unwrap(); let bank_redirect_billing = BankDebitBilling { name: Some(test_first_name.clone()), @@ -8415,7 +8419,10 @@ 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_SINGLE.into())), + card_holder_name: Some( + common_utils::types::NameType::try_from(TEST_FIRST_NAME_SINGLE.to_string()) + .unwrap(), + ), ..Default::default() }); @@ -8424,7 +8431,11 @@ mod billing_from_payment_method_data { let billing_address = billing_address.unwrap(); assert_eq!( - billing_address.address.unwrap().first_name.expose_option(), + billing_address + .address + .unwrap() + .first_name + .map(String::from), Some(TEST_FIRST_NAME_SINGLE.into()) ); } @@ -8441,7 +8452,9 @@ mod billing_from_payment_method_data { #[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())), + card_holder_name: Some( + common_utils::types::NameType::try_from(TEST_FULL_NAME.to_string()).unwrap(), + ), ..Default::default() }); @@ -8449,12 +8462,12 @@ mod billing_from_payment_method_data { let billing_address = billing_details.address.unwrap(); assert_eq!( - billing_address.first_name.expose_option(), + billing_address.first_name.map(String::from), Some(TEST_FIRST_NAME.into()) ); assert_eq!( - billing_address.last_name.expose_option(), + billing_address.last_name.map(String::from), Some(TEST_LAST_NAME.into()) ); } @@ -8462,7 +8475,9 @@ mod billing_from_payment_method_data { #[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())), + card_holder_name: Some( + common_utils::types::NameType::try_from("".to_string()).unwrap(), + ), ..Default::default() }); diff --git a/crates/api_models/src/payments/additional_info.rs b/crates/api_models/src/payments/additional_info.rs index 33297e2b34..fc3ff5d81d 100644 --- a/crates/api_models/src/payments/additional_info.rs +++ b/crates/api_models/src/payments/additional_info.rs @@ -27,11 +27,11 @@ pub struct AchBankDebitAdditionalData { /// Card holder's name #[schema(value_type = Option, example = "John Doe")] - pub card_holder_name: Option>, + pub card_holder_name: Option, /// Bank account's owner name #[schema(value_type = Option, example = "John Doe")] - pub bank_account_holder_name: Option>, + pub bank_account_holder_name: Option, /// Name of the bank #[schema(value_type = Option, example = "ach")] @@ -58,7 +58,7 @@ pub struct BacsBankDebitAdditionalData { /// Bank account's owner name #[schema(value_type = Option, example = "John Doe")] - pub bank_account_holder_name: Option>, + pub bank_account_holder_name: Option, } #[derive(Eq, PartialEq, Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)] @@ -73,7 +73,7 @@ pub struct BecsBankDebitAdditionalData { /// Bank account's owner name #[schema(value_type = Option, example = "John Doe")] - pub bank_account_holder_name: Option>, + pub bank_account_holder_name: Option, } #[derive(Eq, PartialEq, Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)] @@ -84,7 +84,7 @@ pub struct SepaBankDebitAdditionalData { /// Bank account's owner name #[schema(value_type = Option, example = "John Doe")] - pub bank_account_holder_name: Option>, + pub bank_account_holder_name: Option, } #[derive(Eq, PartialEq, Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)] @@ -110,7 +110,7 @@ pub struct BancontactBankRedirectAdditionalData { /// The card holder's name #[schema(value_type = Option, example = "John Test")] - pub card_holder_name: Option>, + pub card_holder_name: Option, } #[derive(Eq, PartialEq, Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)] @@ -194,7 +194,7 @@ pub struct GivexGiftCardAdditionalData { pub struct CardTokenAdditionalData { /// The card holder's name #[schema(value_type = String, example = "John Test")] - pub card_holder_name: Option>, + pub card_holder_name: Option, } #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize, ToSchema)] diff --git a/crates/api_models/src/payouts.rs b/crates/api_models/src/payouts.rs index 4c8a73b75a..8192eabd29 100644 --- a/crates/api_models/src/payouts.rs +++ b/crates/api_models/src/payouts.rs @@ -254,7 +254,7 @@ pub struct CardPayout { /// The card holder's name #[schema(value_type = String, example = "John Doe")] - pub card_holder_name: Option>, + pub card_holder_name: Option, } #[derive(Eq, PartialEq, Clone, Debug, Deserialize, Serialize, ToSchema)] diff --git a/crates/cards/tests/basic.rs b/crates/cards/tests/basic.rs index 0f27c9e028..971cbef32c 100644 --- a/crates/cards/tests/basic.rs +++ b/crates/cards/tests/basic.rs @@ -85,11 +85,11 @@ fn test_card_expiration() { assert!(invalid_card_exp.is_err()); let serialized = serde_json::to_string(&card_exp).unwrap(); - let expected_string = format!(r#"{{"month":{},"year":{}}}"#, 3, curr_year); + let expected_string = format!(r#"{{"month":{},"year":{}}}"#, curr_month, curr_year); assert_eq!(serialized, expected_string); let derialized = serde_json::from_str::(&serialized).unwrap(); - assert_eq!(*derialized.get_month().peek(), 3); + assert_eq!(*derialized.get_month().peek(), curr_month); assert_eq!(*derialized.get_year().peek(), curr_year); let invalid_serialized_string = r#"{"month":13,"year":123}"#; diff --git a/crates/common_utils/src/types.rs b/crates/common_utils/src/types.rs index 11c9b17fae..4bcbc8a454 100644 --- a/crates/common_utils/src/types.rs +++ b/crates/common_utils/src/types.rs @@ -13,9 +13,9 @@ use std::{ borrow::Cow, fmt::Display, iter::Sum, - ops::{Add, Mul, Sub}, + ops::{Add, Deref, Mul, Sub}, primitive::i64, - str::FromStr, + str::{FromStr, SplitWhitespace}, }; use common_enums::enums; @@ -29,6 +29,7 @@ use diesel::{ AsExpression, FromSqlRow, Queryable, }; use error_stack::{report, ResultExt}; +use masking::{ExposeInterface, PeekInterface}; pub use primitive_wrappers::bool_wrappers::{ AlwaysRequestExtendedAuthorization, ExtendedAuthorizationAppliedBool, RequestExtendedAuthorizationBool, @@ -48,6 +49,7 @@ use crate::{ self, MAX_DESCRIPTION_LENGTH, MAX_STATEMENT_DESCRIPTOR_LENGTH, PUBLISHABLE_KEY_LENGTH, }, errors::{CustomResult, ParsingError, PercentageError, ValidationError}, + ext_traits::ConfigExt, fp_utils::when, }; @@ -1100,6 +1102,11 @@ pub(crate) enum LengthStringError { MinLengthViolated(u16), } +impl masking::SerializableSecret + for LengthString +{ +} + impl LengthString { /// Generates new [MerchantReferenceId] from the given input string pub fn from(input_string: Cow<'static, str>) -> Result { @@ -1123,6 +1130,22 @@ impl LengthString Display + for LengthString +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + +impl Default + for LengthString +{ + fn default() -> Self { + Self(String::default()) + } +} + impl<'de, const MAX_LENGTH: u16, const MIN_LENGTH: u16> Deserialize<'de> for LengthString { @@ -1135,6 +1158,13 @@ impl<'de, const MAX_LENGTH: u16, const MIN_LENGTH: u16> Deserialize<'de> } } +impl Deref for LengthString { + type Target = String; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + impl FromSql for LengthString where @@ -1363,6 +1393,173 @@ where } } +#[derive(Clone, Default, Debug, Eq, PartialEq, Serialize)] +/// NewType for validating Names +pub struct NameType(masking::Secret>); + +impl TryFrom for NameType { + type Error = error_stack::Report; + fn try_from(card_holder_name: String) -> Result { + for char in card_holder_name.chars() { + validate_character_in_card_holder_name(char)?; + } + let valid_length_name = + LengthString::<256, 0>::from(card_holder_name.into()).map_err(|_| { + report!(ValidationError::InvalidValue { + message: "invalid length for name".to_string() + }) + })?; + Ok(Self(masking::Secret::new(valid_length_name))) + } +} + +impl TryFrom> for NameType { + type Error = error_stack::Report; + fn try_from(masked_card_holder_name: masking::Secret) -> Result { + Self::try_from(masked_card_holder_name.expose()) + } +} + +impl NameType { + /// This function is used to create NameType from a string without any validation + pub fn get_unchecked(card_holder_name: String) -> Self { + Self(masking::Secret::new(LengthString::<256, 0>::new_unchecked( + card_holder_name, + ))) + } + + /// This function is used to create NameType from a secret of string without any validation + pub fn get_unchecked_from_secret(card_holder_name: masking::Secret) -> Self { + Self(masking::Secret::new(LengthString::<256, 0>::new_unchecked( + card_holder_name.expose(), + ))) + } + + /// Trim the name + pub fn trim(&self) -> Self { + let value = self.0.peek().trim().to_string(); + Self(masking::Secret::new(LengthString::<256, 0>::new_unchecked( + value, + ))) + } + + /// Check if the string is empty + pub fn is_empty(&self) -> bool { + self.0.peek().is_empty() + } + + /// Split the string by whitespace + pub fn split_whitespace(&self) -> SplitWhitespace<'_> { + self.0.peek().split_whitespace() + } + + /// Split once at the first occurrence of the given character + pub fn split_once(&self, delimiter: char) -> Option<(&str, &str)> { + self.0.peek().split_once(delimiter) + } + + /// Split once at the last occurrence of the given character + pub fn rsplit_once(&self, delimiter: char) -> Option<(&str, &str)> { + self.0.peek().rsplit_once(delimiter) + } +} + +impl From for String { + fn from(card_holder_name: NameType) -> Self { + (*(card_holder_name.0.peek())).to_string() + } +} + +impl From<&NameType> for String { + fn from(card_holder_name: &NameType) -> Self { + (*(card_holder_name.0.peek())).to_string() + } +} + +impl FromStr for NameType { + type Err = error_stack::Report; + + fn from_str(card_number: &str) -> Result { + Self::try_from(card_number.to_string()) + } +} + +impl From for masking::Secret { + fn from(card_holder_name: NameType) -> Self { + Self::new(card_holder_name.0.peek().to_string()) + } +} + +impl From<&NameType> for masking::Secret { + fn from(card_holder_name: &NameType) -> Self { + Self::new(card_holder_name.0.peek().to_string()) + } +} + +fn validate_character_in_card_holder_name( + character: char, +) -> Result<(), error_stack::Report> { + if character.is_alphabetic() + || character == ' ' + || character == '.' + || character == '-' + || character == '\'' + || character == '~' + || character == '`' + { + Ok(()) + } else { + Err(report!(ValidationError::InvalidValue { + message: format!("invalid character found in card holder name: {}", character) + })) + } +} + +impl<'de> Deserialize<'de> for NameType { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let card_holder_name = String::deserialize(deserializer)?; + card_holder_name + .try_into() + .map_err(serde::de::Error::custom) + } +} + +impl ConfigExt for NameType { + fn is_empty_after_trim(&self) -> bool { + self.trim().is_empty() + } +} + +#[cfg(test)] +mod name_type_test { + #![allow(clippy::unwrap_used)] + use super::*; + #[test] + fn test_card_holder_name() { + let valid_name = "Sakil Mostak".to_string(); + // no panic + let card_holder_name = NameType::try_from("Sakil Mostak".to_string()).unwrap(); + + // will panic on unwrap + let invalid_card_holder_name = NameType::try_from("$@k!l M*$t@k".to_string()); + + assert_eq!(String::from(card_holder_name.clone()), valid_name); + assert!(invalid_card_holder_name.is_err()); + + let serialized = serde_json::to_string(&card_holder_name).unwrap(); + assert_eq!(&serialized, "\"Sakil Mostak\""); + + let derialized = serde_json::from_str::(&serialized).unwrap(); + assert_eq!(String::from(derialized), valid_name); + + let invalid_deserialization = serde_json::from_str::("$@k!l M*$t@k"); + assert!(invalid_deserialization.is_err()); + } +} + #[cfg(feature = "v2")] /// Browser information to be used for 3DS 2.0 // If any of the field is PII, then we can make them as secret diff --git a/crates/hyperswitch_connectors/src/connectors/adyen/transformers.rs b/crates/hyperswitch_connectors/src/connectors/adyen/transformers.rs index f977ba6a66..a5e814fe9b 100644 --- a/crates/hyperswitch_connectors/src/connectors/adyen/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/adyen/transformers.rs @@ -1937,8 +1937,8 @@ fn get_shopper_name( ) -> Option { let billing = address.and_then(|billing| billing.address.as_ref()); Some(ShopperName { - first_name: billing.and_then(|a| a.first_name.clone()), - last_name: billing.and_then(|a| a.last_name.clone()), + first_name: billing.and_then(|a| a.first_name.clone().map(From::from)), + last_name: billing.and_then(|a| a.last_name.clone().map(From::from)), }) } @@ -2232,6 +2232,7 @@ impl TryFrom<(&WalletData, &PaymentsAuthorizeRouterData)> for AdyenPaymentMethod holder_name: paze_decrypted_data .billing_address .name + .map(From::from) .or(item.get_optional_billing_full_name()), brand: Some(paze_decrypted_data.payment_card_network.clone()) .and_then(get_adyen_card_network), @@ -5140,6 +5141,7 @@ impl TryFrom<&PayoutMethodData> for PayoutCardDetails { holder_name: card .card_holder_name .clone() + .map(From::from) .get_required_value("card_holder_name") .change_context(errors::ConnectorError::MissingRequiredField { field_name: "payout_method_data.card.holder_name", diff --git a/crates/hyperswitch_connectors/src/connectors/authorizedotnet/transformers.rs b/crates/hyperswitch_connectors/src/connectors/authorizedotnet/transformers.rs index deefa7a159..a6798f12ff 100644 --- a/crates/hyperswitch_connectors/src/connectors/authorizedotnet/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/authorizedotnet/transformers.rs @@ -734,8 +734,8 @@ impl .get_optional_billing() .and_then(|billing_address| billing_address.address.as_ref()) .map(|address| BillTo { - first_name: address.first_name.clone(), - last_name: address.last_name.clone(), + first_name: address.first_name.clone().map(From::from), + last_name: address.last_name.clone().map(From::from), address: address.line1.clone(), city: address.city.clone(), state: address.state.clone(), @@ -871,8 +871,8 @@ impl .get_optional_billing() .and_then(|billing_address| billing_address.address.as_ref()) .map(|address| BillTo { - first_name: address.first_name.clone(), - last_name: address.last_name.clone(), + first_name: address.first_name.clone().map(From::from), + last_name: address.last_name.clone().map(From::from), address: address.line1.clone(), city: address.city.clone(), state: address.state.clone(), @@ -945,8 +945,8 @@ impl .get_optional_billing() .and_then(|billing_address| billing_address.address.as_ref()) .map(|address| BillTo { - first_name: address.first_name.clone(), - last_name: address.last_name.clone(), + first_name: address.first_name.clone().map(From::from), + last_name: address.last_name.clone().map(From::from), address: address.line1.clone(), city: address.city.clone(), state: address.state.clone(), diff --git a/crates/hyperswitch_connectors/src/connectors/bankofamerica/transformers.rs b/crates/hyperswitch_connectors/src/connectors/bankofamerica/transformers.rs index 7690b6ed3d..c0cff29184 100644 --- a/crates/hyperswitch_connectors/src/connectors/bankofamerica/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/bankofamerica/transformers.rs @@ -530,8 +530,8 @@ fn build_bill_to( }); BillTo { - first_name: addr.first_name.clone(), - last_name: addr.last_name.clone(), + first_name: addr.first_name.clone().map(From::from), + last_name: addr.last_name.clone().map(From::from), address1: addr.line1.clone(), locality: addr.city.clone(), administrative_area, diff --git a/crates/hyperswitch_connectors/src/connectors/bluesnap/transformers.rs b/crates/hyperswitch_connectors/src/connectors/bluesnap/transformers.rs index 7c49cfe93d..8e0e3d77a0 100644 --- a/crates/hyperswitch_connectors/src/connectors/bluesnap/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/bluesnap/transformers.rs @@ -344,8 +344,8 @@ impl TryFrom<&BluesnapRouterData<&types::PaymentsAuthorizeRouterData>> for Blues billing_contact: BillingDetails { country_code: billing_address.country, address_lines: Some(address), - family_name: billing_address.last_name.to_owned(), - given_name: billing_address.first_name.to_owned(), + family_name: billing_address.last_name.to_owned().map(From::from), + given_name: billing_address.first_name.to_owned().map(From::from), postal_code: billing_address.zip, }, } diff --git a/crates/hyperswitch_connectors/src/connectors/cybersource/transformers.rs b/crates/hyperswitch_connectors/src/connectors/cybersource/transformers.rs index d0d258aaf3..82539f77bb 100644 --- a/crates/hyperswitch_connectors/src/connectors/cybersource/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/cybersource/transformers.rs @@ -1175,8 +1175,8 @@ fn build_bill_to( Ok(address_details .and_then(|addr| { addr.address.as_ref().map(|addr| BillTo { - first_name: addr.first_name.remove_new_line(), - last_name: addr.last_name.remove_new_line(), + first_name: addr.first_name.clone().map(From::from), + last_name: addr.last_name.clone().map(From::from), address1: addr.line1.remove_new_line(), locality: addr.city.remove_new_line(), administrative_area: addr.to_state_code_as_optional().unwrap_or_else(|_| { @@ -1515,7 +1515,6 @@ impl let (first_name, last_name) = match paze_data.billing_address.name { Some(name) => { let (first_name, last_name) = name - .peek() .split_once(' ') .map(|(first, last)| (first.to_string(), last.to_string())) .ok_or(errors::ConnectorError::MissingRequiredField { diff --git a/crates/hyperswitch_connectors/src/connectors/dlocal/transformers.rs b/crates/hyperswitch_connectors/src/connectors/dlocal/transformers.rs index 20b50af355..0314547161 100644 --- a/crates/hyperswitch_connectors/src/connectors/dlocal/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/dlocal/transformers.rs @@ -10,7 +10,7 @@ use hyperswitch_domain_models::{ types, }; use hyperswitch_interfaces::{api::CurrencyUnit, errors}; -use masking::{PeekInterface, Secret}; +use masking::Secret; use serde::{Deserialize, Serialize}; use url::Url; @@ -188,11 +188,11 @@ fn get_payer_name( let first_name = address .first_name .clone() - .map_or("".to_string(), |first_name| first_name.peek().to_string()); + .map_or("".to_string(), String::from); let last_name = address .last_name .clone() - .map_or("".to_string(), |last_name| last_name.peek().to_string()); + .map_or("".to_string(), String::from); let name: String = format!("{first_name} {last_name}").trim().to_string(); if !name.is_empty() { Some(Secret::new(name)) diff --git a/crates/hyperswitch_connectors/src/connectors/nuvei/transformers.rs b/crates/hyperswitch_connectors/src/connectors/nuvei/transformers.rs index cbc4a244d8..ad7b112f1f 100644 --- a/crates/hyperswitch_connectors/src/connectors/nuvei/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/nuvei/transformers.rs @@ -844,9 +844,7 @@ where ( Some(BillingAddress { first_name: Some(first_name.clone()), - last_name: Some( - address.get_last_name().ok().unwrap_or(&first_name).clone(), - ), + last_name: Some(address.get_last_name().ok().unwrap_or(first_name)), email: item.request.get_email_required()?, country: item.get_billing_country()?, }), @@ -1083,7 +1081,7 @@ where let first_name = address.get_first_name()?.clone(); Some(BillingAddress { first_name: Some(first_name.clone()), - last_name: Some(address.get_last_name().ok().unwrap_or(&first_name).clone()), + last_name: Some(address.get_last_name().ok().unwrap_or(first_name)), email: item.request.get_email_required()?, country: item.get_billing_country()?, }) diff --git a/crates/hyperswitch_connectors/src/connectors/paypal/transformers.rs b/crates/hyperswitch_connectors/src/connectors/paypal/transformers.rs index bc5d10620b..a30915c826 100644 --- a/crates/hyperswitch_connectors/src/connectors/paypal/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/paypal/transformers.rs @@ -343,7 +343,7 @@ impl From<&PaypalRouterData<&PaymentsAuthorizeRouterData>> for ShippingAddress { .router_data .get_optional_shipping() .and_then(|inner_data| inner_data.address.as_ref()) - .and_then(|inner_data| inner_data.first_name.clone()), + .and_then(|inner_data| inner_data.first_name.clone().map(From::from)), }), } } @@ -358,7 +358,7 @@ impl From<&PaypalRouterData<&PaymentsPostSessionTokensRouterData>> for ShippingA .router_data .get_optional_shipping() .and_then(|inner_data| inner_data.address.as_ref()) - .and_then(|inner_data| inner_data.first_name.clone()), + .and_then(|inner_data| inner_data.first_name.clone().map(From::from)), }), } } diff --git a/crates/hyperswitch_connectors/src/connectors/trustpay/transformers.rs b/crates/hyperswitch_connectors/src/connectors/trustpay/transformers.rs index c518a6e2d3..fffb191ba0 100644 --- a/crates/hyperswitch_connectors/src/connectors/trustpay/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/trustpay/transformers.rs @@ -321,7 +321,7 @@ fn get_card_request_data( .get_billing()? .address .as_ref() - .and_then(|address| address.last_name.clone()); + .and_then(|address| address.last_name.clone().map(From::from)); Ok(TrustpayPaymentsRequest::CardsPaymentRequest(Box::new( PaymentRequestCards { amount, @@ -374,7 +374,7 @@ fn get_debtor_info( .get_billing()? .address .as_ref() - .and_then(|address| address.last_name.clone()); + .and_then(|address| address.last_name.clone().map(From::from)); Ok(match pm { TrustpayPaymentMethod::Blik => Some(DebtorInformation { name: get_full_name(params.billing_first_name, billing_last_name), @@ -400,7 +400,7 @@ fn get_bank_transfer_debtor_info( Ok(match pm { TrustpayBankTransferPaymentMethod::SepaCreditTransfer | TrustpayBankTransferPaymentMethod::InstantBankTransfer => Some(DebtorInformation { - name: get_full_name(params.billing_first_name, billing_last_name), + name: get_full_name(params.billing_first_name, billing_last_name.map(From::from)), email: item.request.get_email()?, }), }) diff --git a/crates/hyperswitch_connectors/src/connectors/wellsfargo/transformers.rs b/crates/hyperswitch_connectors/src/connectors/wellsfargo/transformers.rs index b346d39686..6837a6e2a7 100644 --- a/crates/hyperswitch_connectors/src/connectors/wellsfargo/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/wellsfargo/transformers.rs @@ -853,8 +853,8 @@ fn build_bill_to( let ad = Ok(address_details .and_then(|addr| { addr.address.as_ref().map(|addr| BillTo { - first_name: addr.first_name.clone(), - last_name: addr.last_name.clone(), + first_name: addr.first_name.clone().map(From::from), + last_name: addr.last_name.clone().map(From::from), address1: addr.line1.clone(), locality: addr.city.clone(), administrative_area: addr.to_state_code_as_optional().ok().flatten(), diff --git a/crates/hyperswitch_connectors/src/connectors/worldline/transformers.rs b/crates/hyperswitch_connectors/src/connectors/worldline/transformers.rs index d716bfd088..03a6d6816e 100644 --- a/crates/hyperswitch_connectors/src/connectors/worldline/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/worldline/transformers.rs @@ -472,11 +472,11 @@ impl From for BillingAddress impl From for Shipping { fn from(value: hyperswitch_domain_models::address::AddressDetails) -> Self { Self { - city: value.city, + city: value.city.clone(), country_code: value.country, name: Some(Name { - first_name: value.first_name, - surname: value.last_name, + first_name: value.first_name.map(From::from), + surname: value.last_name.map(From::from), ..Default::default() }), state: value.state, diff --git a/crates/hyperswitch_connectors/src/utils.rs b/crates/hyperswitch_connectors/src/utils.rs index 40ad127e20..f457a39a99 100644 --- a/crates/hyperswitch_connectors/src/utils.rs +++ b/crates/hyperswitch_connectors/src/utils.rs @@ -553,7 +553,7 @@ impl RouterData shipping_address .clone() .address - .and_then(|shipping_details| shipping_details.first_name) + .and_then(|shipping_details| shipping_details.first_name.map(From::from)) }) } @@ -562,7 +562,7 @@ impl RouterData shipping_address .clone() .address - .and_then(|shipping_details| shipping_details.last_name) + .and_then(|shipping_details| shipping_details.last_name.map(From::from)) }) } @@ -671,7 +671,7 @@ impl RouterData billing_address .clone() .address - .and_then(|billing_details| billing_details.first_name.clone()) + .and_then(|billing_details| billing_details.first_name.map(From::from)) }) .ok_or_else(missing_field_err( "payment_method_data.billing.address.first_name", @@ -694,7 +694,7 @@ impl RouterData billing_address .clone() .address - .and_then(|billing_details| billing_details.last_name.clone()) + .and_then(|billing_details| billing_details.last_name.map(From::from)) }) .ok_or_else(missing_field_err( "payment_method_data.billing.address.last_name", @@ -877,7 +877,7 @@ impl RouterData billing_address .clone() .address - .and_then(|billing_details| billing_details.first_name) + .and_then(|billing_details| billing_details.first_name.map(From::from)) }) } @@ -888,7 +888,7 @@ impl RouterData billing_address .clone() .address - .and_then(|billing_details| billing_details.last_name) + .and_then(|billing_details| billing_details.last_name.map(From::from)) }) } @@ -1151,6 +1151,7 @@ impl CardData for Card { fn get_cardholder_name(&self) -> Result, Error> { self.card_holder_name .clone() + .map(From::from) .ok_or_else(missing_field_err("card.card_holder_name")) } } @@ -1258,6 +1259,7 @@ impl CardData for CardDetailsForNetworkTransactionId { fn get_cardholder_name(&self) -> Result, Error> { self.card_holder_name .clone() + .map(From::from) .ok_or_else(missing_field_err("card.card_holder_name")) } } @@ -1302,8 +1304,8 @@ static CARD_REGEX: Lazy>> = Lazy }); pub trait AddressDetailsData { - fn get_first_name(&self) -> Result<&Secret, Error>; - fn get_last_name(&self) -> Result<&Secret, Error>; + fn get_first_name(&self) -> Result, Error>; + fn get_last_name(&self) -> Result, Error>; fn get_full_name(&self) -> Result, Error>; fn get_line1(&self) -> Result<&Secret, Error>; fn get_city(&self) -> Result<&String, Error>; @@ -1326,26 +1328,23 @@ pub trait AddressDetailsData { } impl AddressDetailsData for AddressDetails { - fn get_first_name(&self) -> Result<&Secret, Error> { + fn get_first_name(&self) -> Result, Error> { self.first_name - .as_ref() + .clone() + .map(From::from) .ok_or_else(missing_field_err("address.first_name")) } - fn get_last_name(&self) -> Result<&Secret, Error> { + fn get_last_name(&self) -> Result, Error> { self.last_name - .as_ref() + .clone() + .map(From::from) .ok_or_else(missing_field_err("address.last_name")) } fn get_full_name(&self) -> Result, Error> { - let first_name = self.get_first_name()?.peek().to_owned(); - let last_name = self - .get_last_name() - .ok() - .cloned() - .unwrap_or(Secret::new("".to_string())); - let last_name = last_name.peek(); + let first_name = self.get_first_name()?.expose(); + let last_name = self.get_last_name().unwrap_or_default().expose(); let full_name = format!("{} {}", first_name, last_name).trim().to_string(); Ok(Secret::new(full_name)) } @@ -1538,11 +1537,11 @@ impl AddressDetailsData for AddressDetails { } fn get_optional_first_name(&self) -> Option> { - self.first_name.clone() + self.first_name.clone().map(From::from) } fn get_optional_last_name(&self) -> Option> { - self.last_name.clone() + self.last_name.clone().map(From::from) } fn get_optional_country(&self) -> Option { @@ -1846,6 +1845,7 @@ impl PaymentsAuthorizeRequestData for PaymentsAuthorizeData { Some(payments::AdditionalPaymentData::Card(card_data)) => Ok(card_data .card_holder_name .clone() + .map(From::from) .ok_or_else(|| errors::ConnectorError::MissingRequiredField { field_name: "card_holder_name", })?), @@ -5859,6 +5859,7 @@ impl CardData for api_models::payouts::CardPayout { fn get_cardholder_name(&self) -> Result, Error> { self.card_holder_name .clone() + .map(From::from) .ok_or_else(missing_field_err("card.card_holder_name")) } } diff --git a/crates/hyperswitch_domain_models/src/address.rs b/crates/hyperswitch_domain_models/src/address.rs index f8e38ae8a3..79b19a52c9 100644 --- a/crates/hyperswitch_domain_models/src/address.rs +++ b/crates/hyperswitch_domain_models/src/address.rs @@ -1,4 +1,4 @@ -use masking::{PeekInterface, Secret}; +use masking::Secret; #[derive(Default, Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)] pub struct Address { @@ -48,8 +48,8 @@ pub struct AddressDetails { pub line3: Option>, pub zip: Option>, pub state: Option>, - pub first_name: Option>, - pub last_name: Option>, + pub first_name: Option, + pub last_name: Option, } impl AddressDetails { @@ -57,10 +57,10 @@ impl AddressDetails { 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() + String::from(first_name), + String::from(last_name) ))), - (Some(name), None) | (None, Some(name)) => Some(name.to_owned()), + (Some(name), None) | (None, Some(name)) => Some(Secret::from(name)), _ => None, } } @@ -71,7 +71,7 @@ impl AddressDetails { let (first_name, last_name) = if self .first_name .as_ref() - .is_some_and(|first_name| !first_name.peek().trim().is_empty()) + .is_some_and(|first_name| !first_name.trim().is_empty()) { (self.first_name.clone(), self.last_name.clone()) } else { diff --git a/crates/hyperswitch_domain_models/src/bulk_tokenization.rs b/crates/hyperswitch_domain_models/src/bulk_tokenization.rs index 0eff34a1bf..fef8d9606d 100644 --- a/crates/hyperswitch_domain_models/src/bulk_tokenization.rs +++ b/crates/hyperswitch_domain_models/src/bulk_tokenization.rs @@ -35,8 +35,8 @@ pub struct TokenizeCardRequest { pub card_expiry_month: masking::Secret, pub card_expiry_year: masking::Secret, pub card_cvc: Option>, - pub card_holder_name: Option>, - pub nick_name: Option>, + pub card_holder_name: Option, + pub nick_name: Option, pub card_issuing_country: Option, pub card_network: Option, pub card_issuer: Option, @@ -56,8 +56,8 @@ pub struct CardNetworkTokenizeRecord { pub card_expiry_month: Option>, pub card_expiry_year: Option>, pub card_cvc: Option>, - pub card_holder_name: Option>, - pub nick_name: Option>, + pub card_holder_name: Option, + pub nick_name: Option, pub card_issuing_country: Option, pub card_network: Option, pub card_issuer: Option, @@ -87,8 +87,8 @@ pub struct CardNetworkTokenizeRecord { pub billing_address_line3: Option>, pub billing_address_zip: Option>, pub billing_address_state: Option>, - pub billing_address_first_name: Option>, - pub billing_address_last_name: Option>, + pub billing_address_first_name: Option, + pub billing_address_last_name: Option, pub billing_phone_number: Option>, pub billing_phone_country_code: Option, pub billing_email: Option, diff --git a/crates/hyperswitch_domain_models/src/payment_method_data.rs b/crates/hyperswitch_domain_models/src/payment_method_data.rs index 1f99e5cbfb..02920de609 100644 --- a/crates/hyperswitch_domain_models/src/payment_method_data.rs +++ b/crates/hyperswitch_domain_models/src/payment_method_data.rs @@ -88,8 +88,8 @@ pub struct Card { pub card_type: Option, pub card_issuing_country: Option, pub bank_code: Option, - pub nick_name: Option>, - pub card_holder_name: Option>, + pub nick_name: Option, + pub card_holder_name: Option, } #[derive(Eq, PartialEq, Clone, Debug, Serialize, Deserialize, Default)] @@ -102,8 +102,8 @@ pub struct CardDetailsForNetworkTransactionId { pub card_type: Option, pub card_issuing_country: Option, pub bank_code: Option, - pub nick_name: Option>, - pub card_holder_name: Option>, + pub nick_name: Option, + pub card_holder_name: Option, } #[derive(Eq, PartialEq, Clone, Debug, Serialize, Deserialize, Default)] @@ -116,8 +116,8 @@ pub struct CardDetail { pub card_type: Option, pub card_issuing_country: Option, pub bank_code: Option, - pub nick_name: Option>, - pub card_holder_name: Option>, + pub nick_name: Option, + pub card_holder_name: Option, } impl CardDetailsForNetworkTransactionId { @@ -413,7 +413,7 @@ pub enum BankRedirectData { card_number: Option, card_exp_month: Option>, card_exp_year: Option>, - card_holder_name: Option>, + card_holder_name: Option, }, Bizum {}, Blik { @@ -556,7 +556,7 @@ pub struct GiftCardDetails { #[serde(rename_all = "snake_case")] pub struct CardToken { /// The card holder's name - pub card_holder_name: Option>, + pub card_holder_name: Option, /// The CVC number for the card pub card_cvc: Option>, @@ -568,25 +568,25 @@ pub enum BankDebitData { AchBankDebit { account_number: Secret, routing_number: Secret, - card_holder_name: Option>, - bank_account_holder_name: Option>, + card_holder_name: Option, + bank_account_holder_name: Option, bank_name: Option, bank_type: Option, bank_holder_type: Option, }, SepaBankDebit { iban: Secret, - bank_account_holder_name: Option>, + bank_account_holder_name: Option, }, BecsBankDebit { account_number: Secret, bsb_number: Secret, - bank_account_holder_name: Option>, + bank_account_holder_name: Option, }, BacsBankDebit { account_number: Secret, sort_code: Secret, - bank_account_holder_name: Option>, + bank_account_holder_name: Option, }, } @@ -642,7 +642,7 @@ pub struct NetworkTokenData { pub card_type: Option, pub card_issuing_country: Option, pub bank_code: Option, - pub nick_name: Option>, + pub nick_name: Option, pub eci: Option, } @@ -1526,10 +1526,10 @@ pub struct TokenizedCardValue1 { pub card_number: String, pub exp_year: String, pub exp_month: String, - pub nickname: Option, + pub nickname: Option, pub card_last_four: Option, pub card_token: Option, - pub card_holder_name: Option>, + pub card_holder_name: Option, } #[derive(Debug, serde::Serialize, serde::Deserialize)] @@ -1861,8 +1861,8 @@ impl From for CardDetailsPaymentMethod { last4_digits: Some(item.card_number.get_last4()), expiry_month: Some(item.card_exp_month), expiry_year: Some(item.card_exp_year), - card_holder_name: item.card_holder_name, - nick_name: item.nick_name, + card_holder_name: item.card_holder_name.map(From::from), + nick_name: item.nick_name.map(From::from), card_isin: None, card_issuer: item.card_issuer, card_network: item.card_network, diff --git a/crates/hyperswitch_domain_models/src/router_data.rs b/crates/hyperswitch_domain_models/src/router_data.rs index 3953564da3..ce73287ef7 100644 --- a/crates/hyperswitch_domain_models/src/router_data.rs +++ b/crates/hyperswitch_domain_models/src/router_data.rs @@ -315,7 +315,7 @@ pub struct PazeDynamicData { #[derive(Debug, Clone, serde::Deserialize)] #[serde(rename_all = "camelCase")] pub struct PazeAddress { - pub name: Option>, + pub name: Option, pub line1: Option>, pub line2: Option>, pub line3: Option>, diff --git a/crates/hyperswitch_domain_models/src/router_request_types/fraud_check.rs b/crates/hyperswitch_domain_models/src/router_request_types/fraud_check.rs index 4d7f4bfdf4..1e55a8e322 100644 --- a/crates/hyperswitch_domain_models/src/router_request_types/fraud_check.rs +++ b/crates/hyperswitch_domain_models/src/router_request_types/fraud_check.rs @@ -140,7 +140,7 @@ pub struct Product { #[serde_with::skip_serializing_none] #[serde(rename_all = "snake_case")] pub struct Destination { - pub full_name: Secret, + pub full_name: common_utils::types::NameType, pub organization: Option, pub email: Option, pub address: Address, diff --git a/crates/router/src/compatibility/stripe/customers/types.rs b/crates/router/src/compatibility/stripe/customers/types.rs index 83649f9823..8f523be7d7 100644 --- a/crates/router/src/compatibility/stripe/customers/types.rs +++ b/crates/router/src/compatibility/stripe/customers/types.rs @@ -42,7 +42,7 @@ pub struct StripeAddressDetails { pub struct CreateCustomerRequest { pub email: Option, pub invoice_prefix: Option, - pub name: Option>, + pub name: Option, pub phone: Option>, pub address: Option, pub metadata: Option, diff --git a/crates/router/src/compatibility/stripe/payment_intents/types.rs b/crates/router/src/compatibility/stripe/payment_intents/types.rs index 11eddab48f..fa95fe08e3 100644 --- a/crates/router/src/compatibility/stripe/payment_intents/types.rs +++ b/crates/router/src/compatibility/stripe/payment_intents/types.rs @@ -64,7 +64,7 @@ pub struct StripeCard { pub exp_month: masking::Secret, pub exp_year: masking::Secret, pub cvc: masking::Secret, - pub holder_name: Option>, + pub holder_name: Option, } // ApplePay wallet param is not available in stripe Docs @@ -169,7 +169,7 @@ impl From for payments::PaymentMethodData { #[derive(Default, Serialize, PartialEq, Eq, Deserialize, Clone, Debug)] pub struct Shipping { pub address: AddressDetails, - pub name: Option>, + pub name: Option, pub carrier: Option, pub phone: Option>, pub tracking_number: Option>, @@ -950,7 +950,9 @@ fn get_pmd_based_on_payment_method_type( payments::PaymentMethodData::BankRedirect(payments::BankRedirectData::Ideal { billing_details: billing_details.as_ref().map(|billing_data| { payments::BankRedirectBilling { - billing_name: billing_data.get_optional_full_name(), + billing_name: billing_data + .get_optional_full_name() + .map(common_utils::types::NameType::get_unchecked_from_secret), // this is unchecked because the input is coming from a checked type email: billing_data.email.clone(), } }), diff --git a/crates/router/src/compatibility/stripe/setup_intents/types.rs b/crates/router/src/compatibility/stripe/setup_intents/types.rs index 158a134611..a4d6f36e13 100644 --- a/crates/router/src/compatibility/stripe/setup_intents/types.rs +++ b/crates/router/src/compatibility/stripe/setup_intents/types.rs @@ -96,7 +96,9 @@ impl From for payments::Card { card_number: card.number, card_exp_month: card.exp_month, card_exp_year: card.exp_year, - card_holder_name: Some(masking::Secret::new("stripe_cust".to_owned())), + card_holder_name: Some(common_utils::types::NameType::get_unchecked(String::from( + "Stripe_cust", + ))), // this is unchecked because valid input is being provided card_cvc: card.cvc, card_issuer: None, card_network: None, diff --git a/crates/router/src/connector/netcetera/netcetera_types.rs b/crates/router/src/connector/netcetera/netcetera_types.rs index 4869c228b4..12e4199099 100644 --- a/crates/router/src/connector/netcetera/netcetera_types.rs +++ b/crates/router/src/connector/netcetera/netcetera_types.rs @@ -2,9 +2,7 @@ use std::collections::HashMap; use common_utils::{pii::Email, types::SemanticVersion}; use hyperswitch_connectors::utils::AddressDetailsData; -use masking::ExposeInterface; use serde::{Deserialize, Serialize}; -use unidecode::unidecode; use crate::{connector::utils::PhoneDetailsData, errors, types::api::MessageCategory}; @@ -825,11 +823,9 @@ impl .clone() .map(PhoneNumber::try_from) .transpose()?, - cardholder_name: billing_address.address.and_then(|address| { - address - .get_optional_full_name() - .map(|name| masking::Secret::new(unidecode(&name.expose()))) - }), + cardholder_name: billing_address + .address + .and_then(|address| address.get_optional_full_name()), ship_addr_city: shipping_address .as_ref() .and_then(|shipping_add| shipping_add.address.as_ref()) diff --git a/crates/router/src/connector/payone/transformers.rs b/crates/router/src/connector/payone/transformers.rs index 2ac9c08301..0e4593baaf 100644 --- a/crates/router/src/connector/payone/transformers.rs +++ b/crates/router/src/connector/payone/transformers.rs @@ -146,6 +146,7 @@ impl TryFrom>> card_holder_name: card_data .card_holder_name .clone() + .map(From::from) .get_required_value("card_holder_name") .change_context(errors::ConnectorError::MissingRequiredField { field_name: "payout_method_data.card.holder_name", diff --git a/crates/router/src/connector/riskified/transformers/api.rs b/crates/router/src/connector/riskified/transformers/api.rs index e8c1b87441..e882aafe8a 100644 --- a/crates/router/src/connector/riskified/transformers/api.rs +++ b/crates/router/src/connector/riskified/transformers/api.rs @@ -227,8 +227,8 @@ impl TryFrom<&RiskifiedRouterData<&frm_types::FrmCheckoutRouterData>> customer: RiskifiedCustomer { email: payment_data.request.email.clone(), - first_name: address.get_first_name().ok().cloned(), - last_name: address.get_last_name().ok().cloned(), + first_name: address.get_first_name().ok(), + last_name: address.get_last_name().ok(), created_at: common_utils::date_time::now(), verified_email: false, id: payment_data.get_customer_id()?, @@ -633,8 +633,8 @@ impl TryFrom<&hyperswitch_domain_models::address::Address> for OrderAddress { field_name: "address", })?; Ok(Self { - first_name: address.first_name.clone(), - last_name: address.last_name.clone(), + first_name: address.first_name.clone().map(From::from), + last_name: address.last_name.clone().map(From::from), address1: address.line1.clone(), country_code: address.country, city: address.city.clone(), diff --git a/crates/router/src/connector/signifyd/transformers/api.rs b/crates/router/src/connector/signifyd/transformers/api.rs index 028c0e8251..45cc7e5061 100644 --- a/crates/router/src/connector/signifyd/transformers/api.rs +++ b/crates/router/src/connector/signifyd/transformers/api.rs @@ -562,7 +562,7 @@ impl From for Product { impl From for Destination { fn from(destination: core_types::Destination) -> Self { Self { - full_name: destination.full_name, + full_name: destination.full_name.into(), organization: destination.organization, email: destination.email, address: Address::from(destination.address), diff --git a/crates/router/src/connector/stripe/transformers.rs b/crates/router/src/connector/stripe/transformers.rs index d9ce3fd28c..88bb8301fa 100644 --- a/crates/router/src/connector/stripe/transformers.rs +++ b/crates/router/src/connector/stripe/transformers.rs @@ -1678,11 +1678,11 @@ impl TryFrom<(&types::PaymentsAuthorizeRouterData, MinorUnit)> for PaymentIntent state: shipping_address.and_then(|a| a.state.clone()), name: format!( "{} {}", - first_name.clone().expose(), + String::from(first_name), shipping_detail .last_name .clone() - .expose_option() + .map(String::from) .unwrap_or_default() ) .into(), @@ -1714,8 +1714,8 @@ impl TryFrom<(&types::PaymentsAuthorizeRouterData, MinorUnit)> for PaymentIntent a.first_name.as_ref().map(|first_name| { format!( "{} {}", - first_name.clone().expose(), - a.last_name.clone().expose_option().unwrap_or_default() + String::from(first_name), + a.last_name.clone().map(String::from).unwrap_or_default() ) .into() }) diff --git a/crates/router/src/connector/stripe/transformers/connect.rs b/crates/router/src/connector/stripe/transformers/connect.rs index 9852338038..c749209509 100644 --- a/crates/router/src/connector/stripe/transformers/connect.rs +++ b/crates/router/src/connector/stripe/transformers/connect.rs @@ -124,9 +124,9 @@ pub struct StripeConnectRecipientCreateRequest { #[serde(rename = "company[owners_provided]")] company_owners_provided: Option, #[serde(rename = "individual[first_name]")] - individual_first_name: Option>, + individual_first_name: Option, #[serde(rename = "individual[last_name]")] - individual_last_name: Option>, + individual_last_name: Option, #[serde(rename = "individual[dob][day]")] individual_dob_day: Option>, #[serde(rename = "individual[dob][month]")] diff --git a/crates/router/src/connector/utils.rs b/crates/router/src/connector/utils.rs index e6a69701ec..dfb8a89791 100644 --- a/crates/router/src/connector/utils.rs +++ b/crates/router/src/connector/utils.rs @@ -236,7 +236,7 @@ impl RouterData for types::RouterData RouterData for types::RouterData RouterData for types::RouterData RouterData for types::RouterData RouterData for types::RouterData RouterData for types::RouterData Result<&Secret, Error>; - fn get_last_name(&self) -> Result<&Secret, Error>; + fn get_first_name(&self) -> Result, Error>; + fn get_last_name(&self) -> Result, Error>; fn get_full_name(&self) -> Result, Error>; fn get_line1(&self) -> Result<&Secret, Error>; fn get_city(&self) -> Result<&String, Error>; @@ -1862,15 +1862,17 @@ pub trait AddressDetailsData { } impl AddressDetailsData for hyperswitch_domain_models::address::AddressDetails { - fn get_first_name(&self) -> Result<&Secret, Error> { + fn get_first_name(&self) -> Result, Error> { self.first_name - .as_ref() + .clone() + .map(From::from) .ok_or_else(missing_field_err("address.first_name")) } - fn get_last_name(&self) -> Result<&Secret, Error> { + fn get_last_name(&self) -> Result, Error> { self.last_name - .as_ref() + .clone() + .map(From::from) .ok_or_else(missing_field_err("address.last_name")) } @@ -1879,7 +1881,6 @@ impl AddressDetailsData for hyperswitch_domain_models::address::AddressDetails { let last_name = self .get_last_name() .ok() - .cloned() .unwrap_or(Secret::new("".to_string())); let last_name = last_name.peek(); let full_name = format!("{} {}", first_name, last_name).trim().to_string(); diff --git a/crates/router/src/core/customers.rs b/crates/router/src/core/customers.rs index c46cadd1e3..5b4a50784c 100644 --- a/crates/router/src/core/customers.rs +++ b/crates/router/src/core/customers.rs @@ -147,7 +147,7 @@ impl CustomerCreateBridge for customers::CustomerRequest { types::CryptoOperation::BatchEncrypt( domain::FromRequestEncryptableCustomer::to_encryptable( domain::FromRequestEncryptableCustomer { - name: self.name.clone(), + name: self.name.clone().map(From::from), email: self.email.clone().map(|a| a.expose().switch_strategy()), phone: self.phone.clone(), }, diff --git a/crates/router/src/core/locker_migration.rs b/crates/router/src/core/locker_migration.rs index dbadadb3a6..fb7432f44a 100644 --- a/crates/router/src/core/locker_migration.rs +++ b/crates/router/src/core/locker_migration.rs @@ -165,7 +165,7 @@ pub async fn call_to_locker( card_exp_month: card.card_exp_month, card_exp_year: card.card_exp_year, card_holder_name: card.name_on_card, - nick_name: card.nick_name.map(masking::Secret::new), + nick_name: card.nick_name, card_issuing_country: None, card_network: None, card_issuer: None, diff --git a/crates/router/src/core/payment_methods.rs b/crates/router/src/core/payment_methods.rs index fee2061e67..bead42695e 100644 --- a/crates/router/src/core/payment_methods.rs +++ b/crates/router/src/core/payment_methods.rs @@ -780,7 +780,8 @@ 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: billing_name, + card_holder_name: card.card_holder_name.clone().or(billing_name + .map(common_utils::types::NameType::get_unchecked_from_secret)), // this is unchecked because billing name is coming from a checked type 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/payment_methods/cards.rs b/crates/router/src/core/payment_methods/cards.rs index dc79cd6845..0898ff2708 100644 --- a/crates/router/src/core/payment_methods/cards.rs +++ b/crates/router/src/core/payment_methods/cards.rs @@ -2326,21 +2326,15 @@ pub fn validate_payment_method_update( }) || card_updation_obj .card_holder_name - .map(|name| name.expose()) + .map(String::from) .is_some_and(|new_card_holder_name| { - existing_card_data - .card_holder_name - .map(|name| name.expose()) - != Some(new_card_holder_name) + existing_card_data.card_holder_name.map(String::from) != Some(new_card_holder_name) }) || card_updation_obj .nick_name - .map(|nick_name| nick_name.expose()) + .map(String::from) .is_some_and(|new_nick_name| { - existing_card_data - .nick_name - .map(|nick_name| nick_name.expose()) - != Some(new_nick_name) + existing_card_data.nick_name.map(String::from) != Some(new_nick_name) }) } @@ -2573,7 +2567,7 @@ pub async fn add_card_hs( card_exp_year: card.card_exp_year.to_owned(), card_brand: card.card_network.as_ref().map(ToString::to_string), card_isin: None, - nick_name: card.nick_name.as_ref().map(Secret::peek).cloned(), + nick_name: card.nick_name.to_owned(), }, ttl: state.conf.locker.ttl_for_storage_in_secs, }); @@ -2996,8 +2990,12 @@ pub async fn mock_call_to_locker_hs( card_number: store_card_req.card.card_number.peek().to_string(), card_exp_year: store_card_req.card.card_exp_year.peek().to_string(), card_exp_month: store_card_req.card.card_exp_month.peek().to_string(), - name_on_card: store_card_req.card.name_on_card.to_owned().expose_option(), - nickname: store_card_req.card.nick_name.to_owned(), + name_on_card: store_card_req + .card + .name_on_card + .to_owned() + .map(String::from), + nickname: store_card_req.card.nick_name.to_owned().map(String::from), ..locker_mock_up }, payment_methods::StoreLockerReq::LockerGeneric(store_generic_req) => { @@ -3048,8 +3046,16 @@ pub async fn mock_get_card<'a>( .map(Some)?, card_exp_year: Some(locker_mock_up.card_exp_year.into()), card_exp_month: Some(locker_mock_up.card_exp_month.into()), - name_on_card: locker_mock_up.name_on_card.map(|card| card.into()), - nickname: locker_mock_up.nickname, + name_on_card: locker_mock_up + .name_on_card + .map(common_utils::types::NameType::try_from) + .transpose() + .change_context(errors::VaultError::ResponseDeserializationFailed)?, + nickname: locker_mock_up + .nickname + .map(common_utils::types::NameType::try_from) + .transpose() + .change_context(errors::VaultError::ResponseDeserializationFailed)?, customer_id: locker_mock_up.customer_id, duplicate: locker_mock_up.duplicate, }; @@ -5676,16 +5682,12 @@ impl TempLockerCardSupport { .clone() .expose_option() .get_required_value("expiry_year")?; - let card_holder_name = card - .card_holder_name - .clone() - .expose_option() - .unwrap_or_default(); + let card_holder_name = card.card_holder_name.clone(); let value1 = payment_methods::mk_card_value1( card_number, card_exp_year, card_exp_month, - Some(card_holder_name), + card_holder_name, None, None, None, @@ -6152,7 +6154,7 @@ pub async fn execute_payment_method_tokenization( &network_token_details, &customer.id, card_details.name_on_card.clone(), - card_details.nick_name.clone().map(Secret::new), + card_details.nick_name.clone(), ) .await?; let builder = builder.set_stored_token_response(&store_token_resp); diff --git a/crates/router/src/core/payment_methods/network_tokenization.rs b/crates/router/src/core/payment_methods/network_tokenization.rs index 8aa371e7a7..bd9bf07c46 100644 --- a/crates/router/src/core/payment_methods/network_tokenization.rs +++ b/crates/router/src/core/payment_methods/network_tokenization.rs @@ -364,8 +364,8 @@ pub async fn make_card_network_tokenization_request( card_network: Some(resp.card_brand), card_type: card.card_type.clone(), card_issuing_country: card.card_issuing_country, - card_holder_name: card.card_holder_name.clone(), - nick_name: card.nick_name.clone(), + card_holder_name: card.card_holder_name.clone().map(From::from), + nick_name: card.nick_name.clone().map(From::from), }; Ok((network_token_details, network_token_req_ref_id)) } diff --git a/crates/router/src/core/payment_methods/tokenize.rs b/crates/router/src/core/payment_methods/tokenize.rs index bd0a5a2192..92625f8f67 100644 --- a/crates/router/src/core/payment_methods/tokenize.rs +++ b/crates/router/src/core/payment_methods/tokenize.rs @@ -8,7 +8,7 @@ use common_utils::{ }; use error_stack::{report, ResultExt}; use hyperswitch_domain_models::router_request_types as domain_request_types; -use masking::{ExposeInterface, Secret}; +use masking::Secret; use router_env::logger; use super::migration; @@ -234,8 +234,8 @@ pub trait NetworkTokenizationProcess<'a, D> { &self, network_token: &NetworkTokenizationResponse, customer_id: &id_type::CustomerId, - card_holder_name: Option>, - nick_name: Option>, + card_holder_name: Option, + nick_name: Option, ) -> RouterResult; } @@ -386,8 +386,8 @@ where &self, network_token: &NetworkTokenizationResponse, customer_id: &id_type::CustomerId, - card_holder_name: Option>, - nick_name: Option>, + card_holder_name: Option, + nick_name: Option, ) -> RouterResult { let network_token = &network_token.0; let merchant_id = self.merchant_account.get_id(); @@ -402,7 +402,7 @@ where card_brand: Some(network_token.card_brand.to_string()), card_isin: Some(network_token.token_isin.clone()), name_on_card: card_holder_name, - nick_name: nick_name.map(|nick_name| nick_name.expose()), + nick_name: nick_name.clone(), }, requestor_card_reference: None, ttl: self.state.conf.locker.ttl_for_storage_in_secs, diff --git a/crates/router/src/core/payment_methods/tokenize/card_executor.rs b/crates/router/src/core/payment_methods/tokenize/card_executor.rs index eb9d3d6b6c..aede4f7a1d 100644 --- a/crates/router/src/core/payment_methods/tokenize/card_executor.rs +++ b/crates/router/src/core/payment_methods/tokenize/card_executor.rs @@ -489,10 +489,7 @@ impl CardNetworkTokenizeExecutor<'_, domain::TokenizeCardRequest> { card_exp_year: card.card_exp_year.clone(), card_isin: Some(card.card_number.get_card_isin().clone()), name_on_card: card.card_holder_name.clone(), - nick_name: card - .nick_name - .as_ref() - .map(|nick_name| nick_name.clone().expose()), + nick_name: card.nick_name.clone(), card_brand: None, }, requestor_card_reference: None, diff --git a/crates/router/src/core/payment_methods/tokenize/payment_method_executor.rs b/crates/router/src/core/payment_methods/tokenize/payment_method_executor.rs index 2249434b10..e06b48bb99 100644 --- a/crates/router/src/core/payment_methods/tokenize/payment_method_executor.rs +++ b/crates/router/src/core/payment_methods/tokenize/payment_method_executor.rs @@ -134,10 +134,7 @@ impl<'a> NetworkTokenizationBuilder<'a, PmValidated> { bank_code: optional_card_info .as_ref() .and_then(|card_info| card_info.bank_code.clone()), - nick_name: card_from_locker - .nick_name - .as_ref() - .map(|nick_name| Secret::new(nick_name.clone())), + nick_name: card_from_locker.nick_name.clone(), card_holder_name: card_from_locker.name_on_card.clone(), card_issuer: optional_card_info .as_ref() diff --git a/crates/router/src/core/payment_methods/transformers.rs b/crates/router/src/core/payment_methods/transformers.rs index a781732960..10c7331dcb 100644 --- a/crates/router/src/core/payment_methods/transformers.rs +++ b/crates/router/src/core/payment_methods/transformers.rs @@ -139,8 +139,8 @@ pub struct AddCardResponse { pub card_number: Option, pub card_exp_year: Option>, pub card_exp_month: Option>, - pub name_on_card: Option>, - pub nickname: Option, + pub name_on_card: Option, + pub nickname: Option, pub customer_id: Option, pub duplicate: Option, } @@ -817,7 +817,7 @@ pub fn get_card_detail( card_token: None, card_fingerprint: None, card_holder_name: response.name_on_card, - nick_name: response.nick_name.map(Secret::new), + nick_name: response.nick_name, card_isin: None, card_issuer: None, card_network: None, @@ -844,7 +844,7 @@ pub fn get_card_detail( expiry_year: Some(response.card_exp_year), card_fingerprint: None, card_holder_name: response.name_on_card, - nick_name: response.nick_name.map(Secret::new), + nick_name: response.nick_name, card_isin: None, card_issuer: None, card_network: None, @@ -886,8 +886,8 @@ pub fn mk_card_value1( card_number: cards::CardNumber, exp_year: String, exp_month: String, - name_on_card: Option, - nickname: Option, + name_on_card: Option, + nickname: Option, card_last_four: Option, card_token: Option, ) -> CustomResult { diff --git a/crates/router/src/core/payment_methods/vault.rs b/crates/router/src/core/payment_methods/vault.rs index 71d57ef796..f3e35a68b8 100644 --- a/crates/router/src/core/payment_methods/vault.rs +++ b/crates/router/src/core/payment_methods/vault.rs @@ -63,7 +63,7 @@ impl Vaultable for domain::Card { card_number: self.card_number.peek().clone(), exp_year: self.card_exp_year.peek().clone(), exp_month: self.card_exp_month.peek().clone(), - nickname: self.nick_name.as_ref().map(|name| name.peek().clone()), + nickname: self.nick_name.clone(), card_last_four: None, card_token: None, card_holder_name: self.card_holder_name.clone(), @@ -119,7 +119,7 @@ impl Vaultable for domain::Card { bank_code: None, card_issuing_country: None, card_type: None, - nick_name: value1.nickname.map(masking::Secret::new), + nick_name: value1.nickname, card_holder_name: value1.card_holder_name, }; @@ -463,7 +463,7 @@ impl Vaultable for api::CardPayout { card_number: self.card_number.peek().clone(), exp_year: self.expiry_year.peek().clone(), exp_month: self.expiry_month.peek().clone(), - name_on_card: self.card_holder_name.clone().map(|n| n.peek().to_string()), + name_on_card: self.card_holder_name.clone(), nickname: None, card_last_four: None, card_token: None, @@ -514,7 +514,7 @@ impl Vaultable for api::CardPayout { .map_err(|_| errors::VaultError::FetchCardFailed)?, expiry_month: value1.exp_month.into(), expiry_year: value1.exp_year.into(), - card_holder_name: value1.name_on_card.map(masking::Secret::new), + card_holder_name: value1.name_on_card, }; let supp_data = SupplementaryVaultData { diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index 190347dfe3..31ba211a60 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -128,11 +128,11 @@ pub async fn create_or_update_address_for_payment_by_request( first_name: address .address .as_ref() - .and_then(|a| a.first_name.clone()), + .and_then(|a| a.first_name.clone().map(From::from)), last_name: address .address .as_ref() - .and_then(|a| a.last_name.clone()), + .and_then(|a| a.last_name.clone().map(From::from)), zip: address.address.as_ref().and_then(|a| a.zip.clone()), phone_number: address .phone @@ -341,8 +341,14 @@ pub async fn get_domain_address( line2: address.address.as_ref().and_then(|a| a.line2.clone()), line3: address.address.as_ref().and_then(|a| a.line3.clone()), state: address.address.as_ref().and_then(|a| a.state.clone()), - first_name: address.address.as_ref().and_then(|a| a.first_name.clone()), - last_name: address.address.as_ref().and_then(|a| a.last_name.clone()), + first_name: address + .address + .as_ref() + .and_then(|a| a.first_name.clone().map(From::from)), + last_name: address + .address + .as_ref() + .and_then(|a| a.last_name.clone().map(From::from)), zip: address.address.as_ref().and_then(|a| a.zip.clone()), phone_number: address .phone @@ -1880,7 +1886,7 @@ pub async fn retrieve_payment_method_with_temporary_token( card_token_data.and_then(|token_data| token_data.card_holder_name.clone()); if let Some(name) = name_on_card.clone() { - if !name.peek().is_empty() { + if !name.is_empty() { is_card_updated = true; updated_card.nick_name = name_on_card; } @@ -2272,7 +2278,7 @@ pub async fn fetch_card_details_from_locker( // The card_holder_name from locker retrieved card is considered if it is a non-empty string or else card_holder_name is picked // from payment_method_data.card_token object let name_on_card = if let Some(name) = card.name_on_card.clone() { - if name.clone().expose().is_empty() { + if name.is_empty() { card_token_data .and_then(|token_data| token_data.card_holder_name.clone()) .or(Some(name)) @@ -2294,7 +2300,7 @@ pub async fn fetch_card_details_from_locker( .card_cvc .unwrap_or_default(), card_issuer: None, - nick_name: card.nick_name.map(masking::Secret::new), + nick_name: card.nick_name, card_network: card .card_brand .map(|card_brand| enums::CardNetwork::from_str(&card_brand)) @@ -2352,7 +2358,7 @@ pub async fn fetch_network_token_details_from_locker( token_cryptogram: None, token_exp_month: token_data.card_exp_month, token_exp_year: token_data.card_exp_year, - nick_name: token_data.nick_name.map(masking::Secret::new), + nick_name: token_data.nick_name, card_issuer: None, card_network, card_type: None, @@ -2399,7 +2405,7 @@ pub async fn fetch_card_details_for_network_transaction_flow_from_locker( card_type: None, card_issuing_country: None, bank_code: None, - nick_name: card_details_from_locker.nick_name.map(masking::Secret::new), + nick_name: card_details_from_locker.nick_name, card_holder_name: card_details_from_locker.name_on_card.clone(), }; diff --git a/crates/router/src/core/payouts/helpers.rs b/crates/router/src/core/payouts/helpers.rs index cdb021311e..5d9888989f 100644 --- a/crates/router/src/core/payouts/helpers.rs +++ b/crates/router/src/core/payouts/helpers.rs @@ -1421,7 +1421,7 @@ pub async fn get_additional_payout_data( card_extended_bin: card_extended_bin.clone(), card_exp_month: Some(card_data.expiry_month.clone()), card_exp_year: Some(card_data.expiry_year.clone()), - card_holder_name: card_data.card_holder_name.clone(), + card_holder_name: card_data.card_holder_name.clone().map(From::from), }, )) }); @@ -1438,7 +1438,7 @@ pub async fn get_additional_payout_data( card_extended_bin, card_exp_month: Some(card_data.expiry_month.clone()), card_exp_year: Some(card_data.expiry_year.clone()), - card_holder_name: card_data.card_holder_name.clone(), + card_holder_name: card_data.card_holder_name.clone().map(From::from), }, )) })) diff --git a/crates/router/src/core/unified_authentication_service.rs b/crates/router/src/core/unified_authentication_service.rs index 787257b57d..2116c98d12 100644 --- a/crates/router/src/core/unified_authentication_service.rs +++ b/crates/router/src/core/unified_authentication_service.rs @@ -258,7 +258,7 @@ impl UnifiedAuthenticationService for ExternalAuthentication payment_data_type: None, encrypted_src_card_details: None, card_expiry_date: card.card_exp_year.clone(), - cardholder_name: card.card_holder_name.clone(), + cardholder_name: card.card_holder_name.clone().map(From::from), card_token_number: card.card_cvc.clone(), account_type: card.card_network.clone(), }) diff --git a/crates/router/src/core/utils.rs b/crates/router/src/core/utils.rs index 87dce4ade0..a9ef9e8068 100644 --- a/crates/router/src/core/utils.rs +++ b/crates/router/src/core/utils.rs @@ -74,6 +74,8 @@ pub async fn construct_payout_router_data<'a, F>( merchant_account: &domain::MerchantAccount, payout_data: &mut PayoutData, ) -> RouterResult> { + use common_utils::types::NameType; + let merchant_connector_account = payout_data .merchant_connector_account .clone() @@ -91,6 +93,16 @@ pub async fn construct_payout_router_data<'a, F>( number: a.phone_number.clone().map(Encryptable::into_inner), country_code: a.country_code.to_owned(), }; + let first_name = a + .first_name + .clone() + .map(Encryptable::into_inner) + .map(NameType::get_unchecked_from_secret); // this is unchecked because this value is fetched from db + let last_name = a + .last_name + .clone() + .map(Encryptable::into_inner) + .map(NameType::get_unchecked_from_secret); // this is unchecked because this value is fetched from db let address_details = api_models::payments::AddressDetails { city: a.city.to_owned(), country: a.country.to_owned(), @@ -98,8 +110,8 @@ pub async fn construct_payout_router_data<'a, F>( line2: a.line2.clone().map(Encryptable::into_inner), line3: a.line3.clone().map(Encryptable::into_inner), zip: a.zip.clone().map(Encryptable::into_inner), - first_name: a.first_name.clone().map(Encryptable::into_inner), - last_name: a.last_name.clone().map(Encryptable::into_inner), + first_name, + last_name, state: a.state.map(Encryptable::into_inner), }; diff --git a/crates/router/src/types/api/payments.rs b/crates/router/src/types/api/payments.rs index 9f509f3bcb..4d1730f644 100644 --- a/crates/router/src/types/api/payments.rs +++ b/crates/router/src/types/api/payments.rs @@ -135,14 +135,18 @@ mod payments_test { card_number: "1234432112344321".to_string().try_into().unwrap(), card_exp_month: "12".to_string().into(), card_exp_year: "99".to_string().into(), - card_holder_name: Some(masking::Secret::new("JohnDoe".to_string())), + card_holder_name: Some(common_utils::types::NameType::get_unchecked( + "JohnDoe".to_string(), + )), card_cvc: "123".to_string().into(), card_issuer: Some("HDFC".to_string()), card_network: Some(api_models::enums::CardNetwork::Visa), bank_code: None, card_issuing_country: None, card_type: None, - nick_name: Some(masking::Secret::new("nick_name".into())), + nick_name: Some(common_utils::types::NameType::get_unchecked( + "nick_name".to_string(), + )), } } diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs index 33ed42efff..df5b4a3e93 100644 --- a/crates/router/src/types/transformers.rs +++ b/crates/router/src/types/transformers.rs @@ -771,6 +771,16 @@ impl From<&domain::Address> for hyperswitch_domain_models::address::Address { { None } else { + let first_name = address + .first_name + .clone() + .map(Encryptable::into_inner) + .map(common_utils::types::NameType::get_unchecked_from_secret); + let last_name = address + .last_name + .clone() + .map(Encryptable::into_inner) + .map(common_utils::types::NameType::get_unchecked_from_secret); Some(hyperswitch_domain_models::address::AddressDetails { city: address.city.clone(), country: address.country, @@ -779,8 +789,8 @@ impl From<&domain::Address> for hyperswitch_domain_models::address::Address { line3: address.line3.clone().map(Encryptable::into_inner), state: address.state.clone().map(Encryptable::into_inner), zip: address.zip.clone().map(Encryptable::into_inner), - first_name: address.first_name.clone().map(Encryptable::into_inner), - last_name: address.last_name.clone().map(Encryptable::into_inner), + first_name, + last_name, }) }; @@ -817,6 +827,16 @@ impl ForeignFrom for api_types::Address { { None } else { + let first_name = address + .first_name + .clone() + .map(Encryptable::into_inner) + .map(common_utils::types::NameType::get_unchecked_from_secret); + let last_name = address + .last_name + .clone() + .map(Encryptable::into_inner) + .map(common_utils::types::NameType::get_unchecked_from_secret); Some(api_types::AddressDetails { city: address.city.clone(), country: address.country, @@ -825,8 +845,8 @@ impl ForeignFrom for api_types::Address { line3: address.line3.clone().map(Encryptable::into_inner), state: address.state.clone().map(Encryptable::into_inner), zip: address.zip.clone().map(Encryptable::into_inner), - first_name: address.first_name.clone().map(Encryptable::into_inner), - last_name: address.last_name.clone().map(Encryptable::into_inner), + first_name, + last_name, }) }; @@ -1791,6 +1811,16 @@ impl ForeignFrom<(storage::PaymentLink, payments::PaymentLinkStatus)> impl From for payments::AddressDetails { fn from(addr: domain::Address) -> Self { + let first_name = addr + .first_name + .clone() + .map(Encryptable::into_inner) + .map(|name| common_utils::types::NameType::get_unchecked(name.expose())); + let last_name = addr + .last_name + .clone() + .map(Encryptable::into_inner) + .map(|name| common_utils::types::NameType::get_unchecked(name.expose())); Self { city: addr.city, country: addr.country, @@ -1799,8 +1829,8 @@ impl From for payments::AddressDetails { line3: addr.line3.map(Encryptable::into_inner), zip: addr.zip.map(Encryptable::into_inner), state: addr.state.map(Encryptable::into_inner), - first_name: addr.first_name.map(Encryptable::into_inner), - last_name: addr.last_name.map(Encryptable::into_inner), + first_name, + last_name, } } } diff --git a/crates/router/src/utils.rs b/crates/router/src/utils.rs index 59ee4e4fb3..9987b52cd0 100644 --- a/crates/router/src/utils.rs +++ b/crates/router/src/utils.rs @@ -780,8 +780,8 @@ impl CustomerAddress for api_models::customers::CustomerRequest { line2: address_details.line2.clone(), line3: address_details.line3.clone(), state: address_details.state.clone(), - first_name: address_details.first_name.clone(), - last_name: address_details.last_name.clone(), + first_name: address_details.first_name.clone().map(From::from), + last_name: address_details.last_name.clone().map(From::from), zip: address_details.zip.clone(), phone_number: self.phone.clone(), email: self @@ -842,8 +842,8 @@ impl CustomerAddress for api_models::customers::CustomerRequest { line2: address_details.line2.clone(), line3: address_details.line3.clone(), state: address_details.state.clone(), - first_name: address_details.first_name.clone(), - last_name: address_details.last_name.clone(), + first_name: address_details.first_name.clone().map(From::from), + last_name: address_details.last_name.clone().map(From::from), zip: address_details.zip.clone(), phone_number: self.phone.clone(), email: self @@ -916,8 +916,8 @@ impl CustomerAddress for api_models::customers::CustomerUpdateRequest { line2: address_details.line2.clone(), line3: address_details.line3.clone(), state: address_details.state.clone(), - first_name: address_details.first_name.clone(), - last_name: address_details.last_name.clone(), + first_name: address_details.first_name.clone().map(From::from), + last_name: address_details.last_name.clone().map(From::from), zip: address_details.zip.clone(), phone_number: self.phone.clone(), email: self @@ -977,8 +977,8 @@ impl CustomerAddress for api_models::customers::CustomerUpdateRequest { line2: address_details.line2.clone(), line3: address_details.line3.clone(), state: address_details.state.clone(), - first_name: address_details.first_name.clone(), - last_name: address_details.last_name.clone(), + first_name: address_details.first_name.clone().map(From::from), + last_name: address_details.last_name.clone().map(From::from), zip: address_details.zip.clone(), phone_number: self.phone.clone(), email: self diff --git a/crates/router/tests/connectors/aci.rs b/crates/router/tests/connectors/aci.rs index 8b3372d7de..b49b788325 100644 --- a/crates/router/tests/connectors/aci.rs +++ b/crates/router/tests/connectors/aci.rs @@ -50,8 +50,12 @@ fn construct_payment_router_data() -> types::PaymentsAuthorizeRouterData { card_type: None, card_issuing_country: None, bank_code: None, - nick_name: Some(Secret::new("nick_name".into())), - card_holder_name: Some(Secret::new("card holder name".into())), + nick_name: Some(common_utils::types::NameType::get_unchecked( + "nick_name".to_string(), + )), + card_holder_name: Some(common_utils::types::NameType::get_unchecked( + "card holder name".to_string(), + )), }), confirm: true, statement_descriptor_suffix: None, @@ -88,8 +92,12 @@ fn construct_payment_router_data() -> types::PaymentsAuthorizeRouterData { None, Some(Address { address: Some(AddressDetails { - first_name: Some(Secret::new("John".to_string())), - last_name: Some(Secret::new("Doe".to_string())), + first_name: Some(common_utils::types::NameType::get_unchecked( + "John".to_string(), + )), + last_name: Some(common_utils::types::NameType::get_unchecked( + "Doe".to_string(), + )), ..Default::default() }), phone: Some(PhoneDetails { @@ -300,8 +308,12 @@ async fn payments_create_failure() { card_type: None, card_issuing_country: None, bank_code: None, - nick_name: Some(Secret::new("nick_name".into())), - card_holder_name: Some(Secret::new("card holder name".into())), + nick_name: Some(common_utils::types::NameType::get_unchecked( + "nick_name".to_string(), + )), + card_holder_name: Some(common_utils::types::NameType::get_unchecked( + "card holder name".to_string(), + )), }); let response = services::api::execute_connector_processing_step( diff --git a/crates/router/tests/connectors/adyen.rs b/crates/router/tests/connectors/adyen.rs index c7ad3b69a3..f57f7e5146 100644 --- a/crates/router/tests/connectors/adyen.rs +++ b/crates/router/tests/connectors/adyen.rs @@ -62,8 +62,12 @@ impl AdyenTest { line1: Some(Secret::new("1467".to_string())), line2: Some(Secret::new("Harrison Street".to_string())), line3: None, - first_name: Some(Secret::new("John".to_string())), - last_name: Some(Secret::new("Dough".to_string())), + first_name: Some(common_utils::types::NameType::get_unchecked( + "John".to_string(), + )), + last_name: Some(common_utils::types::NameType::get_unchecked( + "Dough".to_string(), + )), }), phone: Some(PhoneDetails { number: Some(Secret::new("9123456789".to_string())), @@ -108,7 +112,9 @@ impl AdyenTest { card_number: cards::CardNumber::from_str("4111111111111111").unwrap(), expiry_month: Secret::new("3".to_string()), expiry_year: Secret::new("2030".to_string()), - card_holder_name: Some(Secret::new("John Doe".to_string())), + card_holder_name: Some(common_utils::types::NameType::get_unchecked( + "John Doe".to_string(), + )), }, )), enums::PayoutType::Bank => Some(types::api::PayoutMethodData::Bank( @@ -152,8 +158,12 @@ impl AdyenTest { card_type: None, card_issuing_country: None, bank_code: None, - nick_name: Some(Secret::new("nick_name".into())), - card_holder_name: Some(Secret::new("card holder name".into())), + nick_name: Some(common_utils::types::NameType::get_unchecked( + "nick_name".to_string(), + )), + card_holder_name: Some(common_utils::types::NameType::get_unchecked( + "card holder name".to_string(), + )), }), confirm: true, statement_descriptor_suffix: None, diff --git a/crates/router/tests/connectors/airwallex.rs b/crates/router/tests/connectors/airwallex.rs index 0e538818d5..10fdbff182 100644 --- a/crates/router/tests/connectors/airwallex.rs +++ b/crates/router/tests/connectors/airwallex.rs @@ -57,8 +57,12 @@ fn get_default_payment_info() -> Option { None, Some(Address { address: Some(AddressDetails { - first_name: Some(Secret::new("John".to_string())), - last_name: Some(Secret::new("Doe".to_string())), + first_name: Some(common_utils::types::NameType::get_unchecked( + "John".to_string(), + )), + last_name: Some(common_utils::types::NameType::get_unchecked( + "Doe".to_string(), + )), ..Default::default() }), phone: None, @@ -81,8 +85,11 @@ fn payment_method_details() -> Option { card_type: None, card_issuing_country: None, bank_code: None, - nick_name: Some(Secret::new("nick_name".into())), - card_holder_name: Some(Secret::new("card holder name".into())), + nick_name: common_utils::types::NameType::try_from("nick_name".to_string()).ok(), + card_holder_name: common_utils::types::NameType::try_from( + "card holder name".to_string(), + ) + .ok(), }), capture_method: Some(diesel_models::enums::CaptureMethod::Manual), router_return_url: Some("https://google.com".to_string()), diff --git a/crates/router/tests/connectors/bitpay.rs b/crates/router/tests/connectors/bitpay.rs index 70af3b7521..8e28151959 100644 --- a/crates/router/tests/connectors/bitpay.rs +++ b/crates/router/tests/connectors/bitpay.rs @@ -43,8 +43,12 @@ fn get_default_payment_info() -> Option { None, Some(Address { address: Some(AddressDetails { - first_name: Some(Secret::new("first".to_string())), - last_name: Some(Secret::new("last".to_string())), + first_name: Some(common_utils::types::NameType::get_unchecked( + "first".to_string(), + )), + last_name: Some(common_utils::types::NameType::get_unchecked( + "last".to_string(), + )), line1: Some(Secret::new("line1".to_string())), line2: Some(Secret::new("line2".to_string())), city: Some("city".to_string()), diff --git a/crates/router/tests/connectors/bluesnap.rs b/crates/router/tests/connectors/bluesnap.rs index d6df20d7ee..6ee32b956d 100644 --- a/crates/router/tests/connectors/bluesnap.rs +++ b/crates/router/tests/connectors/bluesnap.rs @@ -50,8 +50,12 @@ fn get_payment_info() -> Option { None, Some(Address { address: Some(AddressDetails { - first_name: Some(Secret::new("joseph".to_string())), - last_name: Some(Secret::new("Doe".to_string())), + first_name: Some(common_utils::types::NameType::get_unchecked( + "joseph".to_string(), + )), + last_name: Some(common_utils::types::NameType::get_unchecked( + "Doe".to_string(), + )), ..Default::default() }), phone: None, diff --git a/crates/router/tests/connectors/coinbase.rs b/crates/router/tests/connectors/coinbase.rs index 7320b875ca..8d4223c0ab 100644 --- a/crates/router/tests/connectors/coinbase.rs +++ b/crates/router/tests/connectors/coinbase.rs @@ -44,8 +44,12 @@ fn get_default_payment_info() -> Option { None, Some(Address { address: Some(AddressDetails { - first_name: Some(Secret::new("first".to_string())), - last_name: Some(Secret::new("last".to_string())), + first_name: Some(common_utils::types::NameType::get_unchecked( + "first".to_string(), + )), + last_name: Some(common_utils::types::NameType::get_unchecked( + "last".to_string(), + )), line1: Some(Secret::new("line1".to_string())), line2: Some(Secret::new("line2".to_string())), city: Some("city".to_string()), diff --git a/crates/router/tests/connectors/cryptopay.rs b/crates/router/tests/connectors/cryptopay.rs index 58fcdc6dae..4cf54789a3 100644 --- a/crates/router/tests/connectors/cryptopay.rs +++ b/crates/router/tests/connectors/cryptopay.rs @@ -43,8 +43,12 @@ fn get_default_payment_info() -> Option { None, Some(Address { address: Some(AddressDetails { - first_name: Some(Secret::new("first".to_string())), - last_name: Some(Secret::new("last".to_string())), + first_name: Some(common_utils::types::NameType::get_unchecked( + "first".to_string(), + )), + last_name: Some(common_utils::types::NameType::get_unchecked( + "last".to_string(), + )), line1: Some(Secret::new("line1".to_string())), line2: Some(Secret::new("line2".to_string())), city: Some("city".to_string()), diff --git a/crates/router/tests/connectors/cybersource.rs b/crates/router/tests/connectors/cybersource.rs index 08001ddd78..0bac235d0f 100644 --- a/crates/router/tests/connectors/cybersource.rs +++ b/crates/router/tests/connectors/cybersource.rs @@ -40,8 +40,12 @@ fn get_default_payment_info() -> Option { None, Some(Address { address: Some(AddressDetails { - first_name: Some(Secret::new("first".to_string())), - last_name: Some(Secret::new("last".to_string())), + first_name: Some(common_utils::types::NameType::get_unchecked( + "first".to_string(), + )), + last_name: Some(common_utils::types::NameType::get_unchecked( + "last".to_string(), + )), line1: Some(Secret::new("line1".to_string())), line2: Some(Secret::new("line2".to_string())), city: Some("city".to_string()), diff --git a/crates/router/tests/connectors/fiserv.rs b/crates/router/tests/connectors/fiserv.rs index 78235278ed..7d11608c63 100644 --- a/crates/router/tests/connectors/fiserv.rs +++ b/crates/router/tests/connectors/fiserv.rs @@ -52,8 +52,12 @@ fn payment_method_details() -> Option { card_type: None, card_issuing_country: None, bank_code: None, - nick_name: Some(Secret::new("nick_name".into())), - card_holder_name: Some(Secret::new("card holder name".into())), + nick_name: Some(common_utils::types::NameType::get_unchecked( + "nick_name".to_string(), + )), + card_holder_name: Some(common_utils::types::NameType::get_unchecked( + "card holder name".to_string(), + )), }), capture_method: Some(diesel_models::enums::CaptureMethod::Manual), ..utils::PaymentAuthorizeType::default().0 diff --git a/crates/router/tests/connectors/forte.rs b/crates/router/tests/connectors/forte.rs index 3c5cde492c..f06f1b7c60 100644 --- a/crates/router/tests/connectors/forte.rs +++ b/crates/router/tests/connectors/forte.rs @@ -57,8 +57,12 @@ fn get_default_payment_info() -> Option { None, Some(Address { address: Some(AddressDetails { - first_name: Some(Secret::new("first".to_string())), - last_name: Some(Secret::new("last".to_string())), + first_name: Some(common_utils::types::NameType::get_unchecked( + "first".to_string(), + )), + last_name: Some(common_utils::types::NameType::get_unchecked( + "last".to_string(), + )), line1: Some(Secret::new("line1".to_string())), line2: Some(Secret::new("line2".to_string())), city: Some("city".to_string()), diff --git a/crates/router/tests/connectors/iatapay.rs b/crates/router/tests/connectors/iatapay.rs index 89fc270e6a..c715e4f740 100644 --- a/crates/router/tests/connectors/iatapay.rs +++ b/crates/router/tests/connectors/iatapay.rs @@ -60,8 +60,12 @@ fn get_default_payment_info() -> Option { None, Some(Address { address: Some(AddressDetails { - first_name: Some(Secret::new("first".to_string())), - last_name: Some(Secret::new("last".to_string())), + first_name: Some(common_utils::types::NameType::get_unchecked( + "first".to_string(), + )), + last_name: Some(common_utils::types::NameType::get_unchecked( + "last".to_string(), + )), line1: Some(Secret::new("line1".to_string())), line2: Some(Secret::new("line2".to_string())), city: Some("city".to_string()), diff --git a/crates/router/tests/connectors/multisafepay.rs b/crates/router/tests/connectors/multisafepay.rs index 1a81b00116..1f88ec0c8d 100644 --- a/crates/router/tests/connectors/multisafepay.rs +++ b/crates/router/tests/connectors/multisafepay.rs @@ -42,8 +42,12 @@ fn get_default_payment_info() -> Option { None, Some(Address { address: Some(AddressDetails { - first_name: Some(Secret::new("John".to_string())), - last_name: Some(Secret::new("Doe".to_string())), + first_name: Some(common_utils::types::NameType::get_unchecked( + "John".to_string(), + )), + last_name: Some(common_utils::types::NameType::get_unchecked( + "Doe".to_string(), + )), line1: Some(Secret::new("Kraanspoor".to_string())), line2: Some(Secret::new("line2".to_string())), line3: Some(Secret::new("line3".to_string())), diff --git a/crates/router/tests/connectors/opennode.rs b/crates/router/tests/connectors/opennode.rs index 6605ea46c3..0c6f375fbd 100644 --- a/crates/router/tests/connectors/opennode.rs +++ b/crates/router/tests/connectors/opennode.rs @@ -43,8 +43,12 @@ fn get_default_payment_info() -> Option { None, Some(Address { address: Some(AddressDetails { - first_name: Some(Secret::new("first".to_string())), - last_name: Some(Secret::new("last".to_string())), + first_name: Some(common_utils::types::NameType::get_unchecked( + "first".to_string(), + )), + last_name: Some(common_utils::types::NameType::get_unchecked( + "last".to_string(), + )), line1: Some(Secret::new("line1".to_string())), line2: Some(Secret::new("line2".to_string())), city: Some("city".to_string()), diff --git a/crates/router/tests/connectors/payme.rs b/crates/router/tests/connectors/payme.rs index b56e1ec83d..b7b6376ec1 100644 --- a/crates/router/tests/connectors/payme.rs +++ b/crates/router/tests/connectors/payme.rs @@ -54,8 +54,12 @@ fn get_default_payment_info() -> Option { line3: None, zip: None, state: None, - first_name: Some(Secret::new("John".to_string())), - last_name: Some(Secret::new("Doe".to_string())), + first_name: Some(common_utils::types::NameType::get_unchecked( + "John".to_string(), + )), + last_name: Some(common_utils::types::NameType::get_unchecked( + "Doe".to_string(), + )), }), phone: None, email: None, diff --git a/crates/router/tests/connectors/rapyd.rs b/crates/router/tests/connectors/rapyd.rs index ee6ac303e8..455d321fc2 100644 --- a/crates/router/tests/connectors/rapyd.rs +++ b/crates/router/tests/connectors/rapyd.rs @@ -52,8 +52,12 @@ async fn should_only_authorize_payment() { card_type: None, card_issuing_country: None, bank_code: None, - nick_name: Some(Secret::new("nick_name".into())), - card_holder_name: Some(Secret::new("card holder name".into())), + nick_name: Some(common_utils::types::NameType::get_unchecked( + "nick_name".to_string(), + )), + card_holder_name: Some(common_utils::types::NameType::get_unchecked( + "card holder name".to_string(), + )), }), capture_method: Some(diesel_models::enums::CaptureMethod::Manual), ..utils::PaymentAuthorizeType::default().0 @@ -80,8 +84,12 @@ async fn should_authorize_and_capture_payment() { card_type: None, card_issuing_country: None, bank_code: None, - nick_name: Some(Secret::new("nick_name".into())), - card_holder_name: Some(Secret::new("card holder name".into())), + nick_name: Some(common_utils::types::NameType::get_unchecked( + "nick_name".to_string(), + )), + card_holder_name: Some(common_utils::types::NameType::get_unchecked( + "card holder name".to_string(), + )), }), ..utils::PaymentAuthorizeType::default().0 }), diff --git a/crates/router/tests/connectors/trustpay.rs b/crates/router/tests/connectors/trustpay.rs index a5eb08c67e..8b6f3910ef 100644 --- a/crates/router/tests/connectors/trustpay.rs +++ b/crates/router/tests/connectors/trustpay.rs @@ -76,8 +76,12 @@ fn get_default_payment_info() -> Option { None, Some(Address { address: Some(AddressDetails { - first_name: Some(Secret::new("first".to_string())), - last_name: Some(Secret::new("last".to_string())), + first_name: Some(common_utils::types::NameType::get_unchecked( + "first".to_string(), + )), + last_name: Some(common_utils::types::NameType::get_unchecked( + "last".to_string(), + )), line1: Some(Secret::new("line1".to_string())), line2: Some(Secret::new("line2".to_string())), city: Some("city".to_string()), diff --git a/crates/router/tests/connectors/utils.rs b/crates/router/tests/connectors/utils.rs index c315200257..405cb54b88 100644 --- a/crates/router/tests/connectors/utils.rs +++ b/crates/router/tests/connectors/utils.rs @@ -79,8 +79,12 @@ impl PaymentInfo { None, Some(hyperswitch_domain_models::address::Address { address: Some(hyperswitch_domain_models::address::AddressDetails { - first_name: Some(Secret::new("John".to_string())), - last_name: Some(Secret::new("Doe".to_string())), + first_name: Some(common_utils::types::NameType::get_unchecked( + "John".to_string(), + )), + last_name: Some(common_utils::types::NameType::get_unchecked( + "Doe".to_string(), + )), ..Default::default() }), phone: None, @@ -938,8 +942,11 @@ impl Default for CCardType { card_type: None, card_issuing_country: None, bank_code: None, - nick_name: Some(Secret::new("nick_name".into())), - card_holder_name: Some(Secret::new("card holder name".into())), + nick_name: common_utils::types::NameType::try_from("nick_name".to_string()).ok(), + card_holder_name: common_utils::types::NameType::try_from( + "card holder name".to_string(), + ) + .ok(), }) } } diff --git a/crates/router/tests/connectors/worldline.rs b/crates/router/tests/connectors/worldline.rs index 793a1cc15f..94f735328b 100644 --- a/crates/router/tests/connectors/worldline.rs +++ b/crates/router/tests/connectors/worldline.rs @@ -48,8 +48,12 @@ 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"))), + first_name: Some(common_utils::types::NameType::get_unchecked( + String::from("John"), + )), + last_name: Some(common_utils::types::NameType::get_unchecked( + String::from("Dough"), + )), ..Default::default() }), phone: None, @@ -82,8 +86,12 @@ impl WorldlineTest { card_type: None, card_issuing_country: None, bank_code: None, - nick_name: Some(Secret::new("nick_name".into())), - card_holder_name: Some(Secret::new("card holder name".into())), + nick_name: Some(common_utils::types::NameType::get_unchecked( + "nick_name".to_string(), + )), + card_holder_name: Some(common_utils::types::NameType::get_unchecked( + "card holder name".to_string(), + )), }), confirm: true, statement_descriptor_suffix: None, diff --git a/crates/router/tests/payments.rs b/crates/router/tests/payments.rs index 0e57540e0e..e85ace6181 100644 --- a/crates/router/tests/payments.rs +++ b/crates/router/tests/payments.rs @@ -342,14 +342,18 @@ async fn payments_create_core() { card_number: "4242424242424242".to_string().try_into().unwrap(), card_exp_month: "10".to_string().into(), card_exp_year: "35".to_string().into(), - card_holder_name: Some(masking::Secret::new("Arun Raj".to_string())), + card_holder_name: Some(common_utils::types::NameType::get_unchecked( + "Arun Raj".to_string(), + )), card_cvc: "123".to_string().into(), card_issuer: None, card_network: None, card_type: None, card_issuing_country: None, bank_code: None, - nick_name: Some(masking::Secret::new("nick_name".into())), + nick_name: Some(common_utils::types::NameType::get_unchecked( + "nick_name".to_string(), + )), })), billing: None, }), @@ -610,14 +614,18 @@ async fn payments_create_core_adyen_no_redirect() { card_number: "5555 3412 4444 1115".to_string().try_into().unwrap(), card_exp_month: "03".to_string().into(), card_exp_year: "2030".to_string().into(), - card_holder_name: Some(masking::Secret::new("JohnDoe".to_string())), + card_holder_name: Some(common_utils::types::NameType::get_unchecked( + "JohnDoe".to_string(), + )), card_cvc: "737".to_string().into(), card_issuer: None, card_network: None, card_type: None, card_issuing_country: None, bank_code: None, - nick_name: Some(masking::Secret::new("nick_name".into())), + nick_name: Some(common_utils::types::NameType::get_unchecked( + "nick_name".to_string(), + )), })), billing: None, }), diff --git a/crates/router/tests/payments2.rs b/crates/router/tests/payments2.rs index 19281b4501..216ca2a7bd 100644 --- a/crates/router/tests/payments2.rs +++ b/crates/router/tests/payments2.rs @@ -103,14 +103,18 @@ async fn payments_create_core() { card_number: "4242424242424242".to_string().try_into().unwrap(), card_exp_month: "10".to_string().into(), card_exp_year: "35".to_string().into(), - card_holder_name: Some(masking::Secret::new("Arun Raj".to_string())), + card_holder_name: Some(common_utils::types::NameType::get_unchecked( + "Arun Raj".to_string(), + )), card_cvc: "123".to_string().into(), card_issuer: None, card_network: None, card_type: None, card_issuing_country: None, bank_code: None, - nick_name: Some(masking::Secret::new("nick_name".into())), + nick_name: Some(common_utils::types::NameType::get_unchecked( + "nick_name".to_string(), + )), })), billing: None, }), @@ -379,14 +383,18 @@ async fn payments_create_core_adyen_no_redirect() { card_number: "5555 3412 4444 1115".to_string().try_into().unwrap(), card_exp_month: "03".to_string().into(), card_exp_year: "2030".to_string().into(), - card_holder_name: Some(masking::Secret::new("JohnDoe".to_string())), + card_holder_name: Some(common_utils::types::NameType::get_unchecked( + "JohnDoe".to_string(), + )), card_cvc: "737".to_string().into(), bank_code: None, card_issuer: None, card_network: None, card_type: None, card_issuing_country: None, - nick_name: Some(masking::Secret::new("nick_name".into())), + nick_name: Some(common_utils::types::NameType::get_unchecked( + "nick_name".to_string(), + )), })), billing: None, }),