mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-30 01:27:31 +08:00
refactor(card): use billing.first_name instead of card_holder_name (#4239)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
@ -4,10 +4,10 @@ use cards::CardNumber;
|
||||
use common_utils::{
|
||||
consts::default_payments_list_limit,
|
||||
crypto,
|
||||
ext_traits::Encode,
|
||||
ext_traits::{ConfigExt, Encode},
|
||||
pii::{self, Email},
|
||||
};
|
||||
use masking::Secret;
|
||||
use masking::{PeekInterface, Secret};
|
||||
use router_derive::Setter;
|
||||
use serde::{
|
||||
de::{self, Unexpected, Visitor},
|
||||
@ -909,6 +909,47 @@ pub struct Card {
|
||||
pub nick_name: Option<Secret<String>>,
|
||||
}
|
||||
|
||||
impl GetAddressFromPaymentMethodData for Card {
|
||||
fn get_billing_address(&self) -> Option<Address> {
|
||||
// Create billing address if first_name is some or if it is not ""
|
||||
self.card_holder_name
|
||||
.as_ref()
|
||||
.filter(|card_holder_name| !card_holder_name.is_empty_after_trim())
|
||||
.map(|card_holder_name| {
|
||||
// Split the `card_holder_name` into `first_name` and `last_name` based on the
|
||||
// first occurrence of ' '. For example
|
||||
// John Wheat Dough
|
||||
// first_name -> John
|
||||
// last_name -> Wheat Dough
|
||||
card_holder_name.peek().split_whitespace()
|
||||
})
|
||||
.map(|mut card_holder_name_iter| {
|
||||
let first_name = card_holder_name_iter
|
||||
.next()
|
||||
.map(ToOwned::to_owned)
|
||||
.map(Secret::new);
|
||||
|
||||
let last_name = card_holder_name_iter.collect::<Vec<_>>().join(" ");
|
||||
let last_name = if last_name.is_empty_after_trim() {
|
||||
None
|
||||
} else {
|
||||
Some(Secret::new(last_name))
|
||||
};
|
||||
|
||||
AddressDetails {
|
||||
first_name,
|
||||
last_name,
|
||||
..Default::default()
|
||||
}
|
||||
})
|
||||
.map(|address_details| Address {
|
||||
address: Some(address_details),
|
||||
phone: None,
|
||||
email: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Card {
|
||||
fn apply_additional_card_info(&self, additional_card_info: AdditionalCardInfo) -> Self {
|
||||
Self {
|
||||
@ -1292,7 +1333,7 @@ pub trait GetAddressFromPaymentMethodData {
|
||||
impl GetAddressFromPaymentMethodData for PaymentMethodData {
|
||||
fn get_billing_address(&self) -> Option<Address> {
|
||||
match self {
|
||||
Self::Card(_) => None,
|
||||
Self::Card(card_data) => card_data.get_billing_address(),
|
||||
Self::CardRedirect(_) => None,
|
||||
Self::Wallet(_) => None,
|
||||
Self::PayLater(_) => None,
|
||||
@ -2647,6 +2688,18 @@ pub struct AddressDetails {
|
||||
}
|
||||
|
||||
impl AddressDetails {
|
||||
pub fn get_optional_full_name(&self) -> Option<Secret<String>> {
|
||||
match (self.first_name.as_ref(), self.last_name.as_ref()) {
|
||||
(Some(first_name), Some(last_name)) => Some(Secret::new(format!(
|
||||
"{} {}",
|
||||
first_name.peek(),
|
||||
last_name.peek()
|
||||
))),
|
||||
(Some(name), None) | (None, Some(name)) => Some(name.to_owned()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unify_address_details(self, other: Option<&Self>) -> Self {
|
||||
if let Some(other) = other {
|
||||
let (first_name, last_name) = if self.first_name.is_some() {
|
||||
@ -4591,11 +4644,15 @@ mod payments_request_api_contract {
|
||||
mod billing_from_payment_method_data {
|
||||
#![allow(clippy::unwrap_used)]
|
||||
use common_enums::CountryAlpha2;
|
||||
use masking::ExposeOptionInterface;
|
||||
|
||||
use super::*;
|
||||
|
||||
const TEST_COUNTRY: CountryAlpha2 = CountryAlpha2::US;
|
||||
const TEST_FIRST_NAME: &str = "John";
|
||||
const TEST_LAST_NAME: &str = "Wheat Dough";
|
||||
const TEST_FULL_NAME: &str = "John Wheat Dough";
|
||||
const TEST_FIRST_NAME_SINGLE: &str = "John";
|
||||
|
||||
#[test]
|
||||
fn test_wallet_payment_method_data_paypal() {
|
||||
@ -4704,15 +4761,17 @@ mod billing_from_payment_method_data {
|
||||
#[test]
|
||||
fn test_card_payment_method_data() {
|
||||
let card_payment_method_data = PaymentMethodData::Card(Card {
|
||||
card_holder_name: Some(Secret::new(TEST_FIRST_NAME.into())),
|
||||
card_holder_name: Some(Secret::new(TEST_FIRST_NAME_SINGLE.into())),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
let billing_address = card_payment_method_data.get_billing_address().unwrap();
|
||||
let billing_address = card_payment_method_data.get_billing_address();
|
||||
|
||||
let billing_address = billing_address.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
billing_address.address.unwrap().first_name.unwrap(),
|
||||
Secret::new(TEST_FIRST_NAME.into())
|
||||
billing_address.address.unwrap().first_name.expose_option(),
|
||||
Some(TEST_FIRST_NAME_SINGLE.into())
|
||||
);
|
||||
}
|
||||
|
||||
@ -4724,4 +4783,37 @@ mod billing_from_payment_method_data {
|
||||
|
||||
assert!(billing_address.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_card_payment_method_data_full_name() {
|
||||
let card_payment_method_data = PaymentMethodData::Card(Card {
|
||||
card_holder_name: Some(Secret::new(TEST_FULL_NAME.into())),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
let billing_details = card_payment_method_data.get_billing_address().unwrap();
|
||||
let billing_address = billing_details.address.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
billing_address.first_name.expose_option(),
|
||||
Some(TEST_FIRST_NAME.into())
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
billing_address.last_name.expose_option(),
|
||||
Some(TEST_LAST_NAME.into())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_card_payment_method_data_empty_string() {
|
||||
let card_payment_method_data = PaymentMethodData::Card(Card {
|
||||
card_holder_name: Some(Secret::new("".to_string())),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
let billing_details = card_payment_method_data.get_billing_address();
|
||||
|
||||
assert!(billing_details.is_none());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user