Bug: [REFACTOR] Make the `card_holder_name` optional for card details in the payment APIs



### Description
We currently have the `card_holder_name` as mandatory for cards in the payment APIs. We currently do not mandatorily collect it for every payment so this causes the SDK to have to send an empty string for payments where the card holder name is not collected. We want to refactor this to allow for `null` values to avoid the need to send empty strings for the SDK.
diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs
index 93c97cbd443..b19f4d7b7db 100644
--- a/crates/api_models/src/payments.rs
+++ b/crates/api_models/src/payments.rs
@@ -682,7 +682,7 @@ pub struct Card {
 
     /// The card holder's name
     #[schema(value_type = String, example = "John Test")]
-    pub card_holder_name: Secret<String>,
+    pub card_holder_name: Option<Secret<String>>,
 
     /// The CVC number for the card
     #[schema(value_type = String, example = "242")]
diff --git a/crates/router/src/compatibility/stripe/payment_intents/types.rs b/crates/router/src/compatibility/stripe/payment_intents/types.rs
index 3c7d5f2918f..38007a3110d 100644
--- a/crates/router/src/compatibility/stripe/payment_intents/types.rs
+++ b/crates/router/src/compatibility/stripe/payment_intents/types.rs
@@ -118,7 +118,7 @@ impl From<StripeCard> for payments::Card {
             card_number: card.number,
             card_exp_month: card.exp_month,
             card_exp_year: card.exp_year,
-            card_holder_name: card.holder_name.unwrap_or("name".to_string().into()),
+            card_holder_name: card.holder_name,
             card_cvc: card.cvc,
             card_issuer: None,
             card_network: None,
diff --git a/crates/router/src/compatibility/stripe/setup_intents/types.rs b/crates/router/src/compatibility/stripe/setup_intents/types.rs
index 9d3f74af8cb..4c99d0cb00b 100644
--- a/crates/router/src/compatibility/stripe/setup_intents/types.rs
+++ b/crates/router/src/compatibility/stripe/setup_intents/types.rs
@@ -95,7 +95,7 @@ impl From<StripeCard> for payments::Card {
             card_number: card.number,
             card_exp_month: card.exp_month,
             card_exp_year: card.exp_year,
-            card_holder_name: masking::Secret::new("stripe_cust".to_owned()),
+            card_holder_name: Some(masking::Secret::new("stripe_cust".to_owned())),
             card_cvc: card.cvc,
             card_issuer: None,
             card_network: None,
diff --git a/crates/router/src/connector/aci/transformers.rs b/crates/router/src/connector/aci/transformers.rs
index 9cfb657bdca..53639f268c8 100644
--- a/crates/router/src/connector/aci/transformers.rs
+++ b/crates/router/src/connector/aci/transformers.rs
@@ -254,7 +254,9 @@ impl TryFrom<api_models::payments::Card> for PaymentDetails {
     fn try_from(card_data: api_models::payments::Card) -> Result<Self, Self::Error> {
         Ok(Self::AciCard(Box::new(CardDetails {
             card_number: card_data.card_number,
-            card_holder: card_data.card_holder_name,
+            card_holder: card_data
+                .card_holder_name
+                .ok_or_else(utils::missing_field_err("card_holder_name"))?,
             card_expiry_month: card_data.card_exp_month,
             card_expiry_year: card_data.card_exp_year,
             card_cvv: card_data.card_cvc,
diff --git a/crates/router/src/connector/bambora/transformers.rs b/crates/router/src/connector/bambora/transformers.rs
index 2d50569f9a4..4729bfa5a6e 100644
--- a/crates/router/src/connector/bambora/transformers.rs
+++ b/crates/router/src/connector/bambora/transformers.rs
@@ -5,7 +5,7 @@ use masking::{PeekInterface, Secret};
 use serde::{Deserialize, Deserializer, Serialize};
 
 use crate::{
-    connector::utils::{BrowserInformationData, PaymentsAuthorizeRequestData},
+    connector::utils::{self, BrowserInformationData, PaymentsAuthorizeRequestData},
     consts,
     core::errors,
     services,
@@ -117,7 +117,9 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for BamboraPaymentsRequest {
                     enums::AuthenticationType::NoThreeDs => None,
                 };
                 let bambora_card = BamboraCard {
-                    name: req_card.card_holder_name,
+                    name: req_card
+                        .card_holder_name
+                        .ok_or_else(utils::missing_field_err("card_holder_name"))?,
                     number: req_card.card_number,
                     expiry_month: req_card.card_exp_month,
                     expiry_year: req_card.card_exp_year,
diff --git a/crates/router/src/connector/braintree/braintree_graphql_transformers.rs b/crates/router/src/connector/braintree/braintree_graphql_transformers.rs
index f6c1bfc46b0..d1201309637 100644
--- a/crates/router/src/connector/braintree/braintree_graphql_transformers.rs
+++ b/crates/router/src/connector/braintree/braintree_graphql_transformers.rs
@@ -867,7 +867,9 @@ impl TryFrom<&types::TokenizationRouterData> for BraintreeTokenRequest {
                         expiration_year: card_data.card_exp_year,
                         expiration_month: card_data.card_exp_month,
                         cvv: card_data.card_cvc,
-                        cardholder_name: card_data.card_holder_name,
+                        cardholder_name: card_data
+                            .card_holder_name
+                            .ok_or_else(utils::missing_field_err("card_holder_name"))?,
                     },
                 };
                 Ok(Self {
diff --git a/crates/router/src/connector/dlocal/transformers.rs b/crates/router/src/connector/dlocal/transformers.rs
index 92d01cfe56d..25462c758f1 100644
--- a/crates/router/src/connector/dlocal/transformers.rs
+++ b/crates/router/src/connector/dlocal/transformers.rs
@@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
 use url::Url;
 
 use crate::{
-    connector::utils::{AddressDetailsData, PaymentsAuthorizeRequestData, RouterData},
+    connector::utils::{self, AddressDetailsData, PaymentsAuthorizeRequestData, RouterData},
     core::errors,
     services,
     types::{self, api, storage::enums},
@@ -125,7 +125,10 @@ impl TryFrom<&DlocalRouterData<&types::PaymentsAuthorizeRouterData>> for DlocalP
                         document: get_doc_from_currency(country.to_string()),
                     },
                     card: Some(Card {
-                        holder_name: ccard.card_holder_name.clone(),
+                        holder_name: ccard
+                            .card_holder_name
+                            .clone()
+                            .ok_or_else(utils::missing_field_err("card_holder_name"))?,
                         number: ccard.card_number.clone(),
                         cvv: ccard.card_cvc.clone(),
                         expiration_month: ccard.card_exp_month.clone(),
diff --git a/crates/router/src/connector/dummyconnector/transformers.rs b/crates/router/src/connector/dummyconnector/transformers.rs
index 3c7bd2e09d9..bbb3b10c8e0 100644
--- a/crates/router/src/connector/dummyconnector/transformers.rs
+++ b/crates/router/src/connector/dummyconnector/transformers.rs
@@ -4,6 +4,7 @@ use serde::{Deserialize, Serialize};
 use url::Url;
 
 use crate::{
+    connector::utils,
     core::errors,
     services,
     types::{self, api, storage::enums},
@@ -83,15 +84,18 @@ pub struct DummyConnectorCard {
     cvc: Secret<String>,
 }
 
-impl From<api_models::payments::Card> for DummyConnectorCard {
-    fn from(value: api_models::payments::Card) -> Self {
-        Self {
-            name: value.card_holder_name,
+impl TryFrom<api_models::payments::Card> for DummyConnectorCard {
+    type Error = error_stack::Report<errors::ConnectorError>;
+    fn try_from(value: api_models::payments::Card) -> Result<Self, Self::Error> {
+        Ok(Self {
+            name: value
+                .card_holder_name
+                .ok_or_else(utils::missing_field_err("card_holder_name"))?,
             number: value.card_number,
             expiry_month: value.card_exp_month,
             expiry_year: value.card_exp_year,
             cvc: value.card_cvc,
-        }
+        })
     }
 }
 
@@ -151,7 +155,7 @@ impl<const T: u8> TryFrom<&types::PaymentsAuthorizeRouterData>
             .payment_method_data
         {
             api::PaymentMethodData::Card(ref req_card) => {
-                Ok(PaymentMethodData::Card(req_card.clone().into()))
+                Ok(PaymentMethodData::Card(req_card.clone().try_into()?))
             }
             api::PaymentMethodData::Wallet(ref wallet_data) => {
                 Ok(PaymentMethodData::Wallet(wallet_data.clone().try_into()?))
diff --git a/crates/router/src/connector/forte/transformers.rs b/crates/router/src/connector/forte/transformers.rs
index 4bb354f6cda..411457fab67 100644
--- a/crates/router/src/connector/forte/transformers.rs
+++ b/crates/router/src/connector/forte/transformers.rs
@@ -82,7 +82,10 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for FortePaymentsRequest {
                 let address = item.get_billing_address()?;
                 let card = Card {
                     card_type,
-                    name_on_card: ccard.card_holder_name.clone(),
+                    name_on_card: ccard
+                        .card_holder_name
+                        .clone()
+                        .ok_or_else(utils::missing_field_err("card_holder_name"))?,
                     account_number: ccard.card_number.clone(),
                     expire_month: ccard.card_exp_month.clone(),
                     expire_year: ccard.card_exp_year.clone(),
diff --git a/crates/router/src/connector/mollie/transformers.rs b/crates/router/src/connector/mollie/transformers.rs
index 62fb94e236a..c1151adcf6d 100644
--- a/crates/router/src/connector/mollie/transformers.rs
+++ b/crates/router/src/connector/mollie/transformers.rs
@@ -286,7 +286,10 @@ impl TryFrom<&types::TokenizationRouterData> for MollieCardTokenRequest {
         match item.request.payment_method_data.clone() {
             api_models::payments::PaymentMethodData::Card(ccard) => {
                 let auth = MollieAuthType::try_from(&item.connector_auth_type)?;
-                let card_holder = ccard.card_holder_name.clone();
+                let card_holder = ccard
+                    .card_holder_name
+                    .clone()
+                    .ok_or_else(utils::missing_field_err("card_holder_name"))?;
                 let card_number = ccard.card_number.clone();
                 let card_expiry_date =
                     ccard.get_card_expiry_month_year_2_digit_with_delimiter("/".to_owned());
diff --git a/crates/router/src/connector/noon/transformers.rs b/crates/router/src/connector/noon/transformers.rs
index b478d63e0f1..e2262e7b895 100644
--- a/crates/router/src/connector/noon/transformers.rs
+++ b/crates/router/src/connector/noon/transformers.rs
@@ -200,7 +200,10 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for NoonPaymentsRequest {
             _ => (
                 match item.request.payment_method_data.clone() {
                     api::PaymentMethodData::Card(req_card) => Ok(NoonPaymentData::Card(NoonCard {
-                        name_on_card: req_card.card_holder_name.clone(),
+                        name_on_card: req_card
+                            .card_holder_name
+                            .clone()
+                            .ok_or_else(conn_utils::missing_field_err("card_holder_name"))?,
                         number_plain: req_card.card_number.clone(),
                         expiry_month: req_card.card_exp_month.clone(),
                         expiry_year: req_card.get_expiry_year_4_digit(),
diff --git a/crates/router/src/connector/nuvei/transformers.rs b/crates/router/src/connector/nuvei/transformers.rs
index 73e039c6339..4ed6b25b136 100644
--- a/crates/router/src/connector/nuvei/transformers.rs
+++ b/crates/router/src/connector/nuvei/transformers.rs
@@ -1000,7 +1000,7 @@ impl From<NuveiCardDetails> for PaymentOption {
         Self {
             card: Some(Card {
                 card_number: Some(card.card_number),
-                card_holder_name: Some(card.card_holder_name),
+                card_holder_name: card.card_holder_name,
                 expiration_month: Some(card.card_exp_month),
                 expiration_year: Some(card.card_exp_year),
                 three_d: card_details.three_d,
diff --git a/crates/router/src/connector/opayo/transformers.rs b/crates/router/src/connector/opayo/transformers.rs
index 7b633f6aa64..a0e3877f82b 100644
--- a/crates/router/src/connector/opayo/transformers.rs
+++ b/crates/router/src/connector/opayo/transformers.rs
@@ -29,7 +29,9 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for OpayoPaymentsRequest {
         match item.request.payment_method_data.clone() {
             api::PaymentMethodData::Card(req_card) => {
                 let card = OpayoCard {
-                    name: req_card.card_holder_name,
+                    name: req_card
+                        .card_holder_name
+                        .ok_or_else(utils::missing_field_err("card_holder_name"))?,
                     number: req_card.card_number,
                     expiry_month: req_card.card_exp_month,
                     expiry_year: req_card.card_exp_year,
diff --git a/crates/router/src/connector/payeezy/transformers.rs b/crates/router/src/connector/payeezy/transformers.rs
index 0170d18ecb4..8b4f4a46959 100644
--- a/crates/router/src/connector/payeezy/transformers.rs
+++ b/crates/router/src/connector/payeezy/transformers.rs
@@ -241,7 +241,10 @@ fn get_payment_method_data(
             let card_type = PayeezyCardType::try_from(card.get_card_issuer()?)?;
             let payeezy_card = PayeezyCard {
                 card_type,
-                cardholder_name: card.card_holder_name.clone(),
+                cardholder_name: card
+                    .card_holder_name
+                    .clone()
+                    .ok_or_else(utils::missing_field_err("card_holder_name"))?,
                 card_number: card.card_number.clone(),
                 exp_date: card.get_card_expiry_month_year_2_digit_with_delimiter("".to_string()),
                 cvv: card.card_cvc.clone(),
diff --git a/crates/router/src/connector/paypal/transformers.rs b/crates/router/src/connector/paypal/transformers.rs
index 8b6a2297d09..0871bc5097a 100644
--- a/crates/router/src/connector/paypal/transformers.rs
+++ b/crates/router/src/connector/paypal/transformers.rs
@@ -443,7 +443,10 @@ impl TryFrom<&PaypalRouterData<&types::PaymentsAuthorizeRouterData>> for PaypalP
                 let payment_source = Some(PaymentSourceItem::Card(CardRequest {
                     billing_address: get_address_info(item.router_data.address.billing.as_ref())?,
                     expiry,
-                    name: ccard.card_holder_name.clone(),
+                    name: ccard
+                        .card_holder_name
+                        .clone()
+                        .ok_or_else(utils::missing_field_err("card_holder_name"))?,
                     number: Some(ccard.card_number.clone()),
                     security_code: Some(ccard.card_cvc.clone()),
                     attributes,
diff --git a/crates/router/src/connector/powertranz/transformers.rs b/crates/router/src/connector/powertranz/transformers.rs
index e0ecd81c7e5..6d5a756c571 100644
--- a/crates/router/src/connector/powertranz/transformers.rs
+++ b/crates/router/src/connector/powertranz/transformers.rs
@@ -101,7 +101,7 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for PowertranzPaymentsRequest
     type Error = error_stack::Report<errors::ConnectorError>;
     fn try_from(item: &types::PaymentsAuthorizeRouterData) -> Result<Self, Self::Error> {
         let source = match item.request.payment_method_data.clone() {
-            api::PaymentMethodData::Card(card) => Ok(Source::from(&card)),
+            api::PaymentMethodData::Card(card) => Source::try_from(&card),
             api::PaymentMethodData::Wallet(_)
             | api::PaymentMethodData::CardRedirect(_)
             | api::PaymentMethodData::PayLater(_)
@@ -211,15 +211,19 @@ impl TryFrom<&types::BrowserInformation> for BrowserInfo {
         })
 }*/
 
-impl From<&Card> for Source {
-    fn from(card: &Card) -> Self {
+impl TryFrom<&Card> for Source {
+    type Error = error_stack::Report<errors::ConnectorError>;
+    fn try_from(card: &Card) -> Result<Self, Self::Error> {
         let card = PowertranzCard {
-            cardholder_name: card.card_holder_name.clone(),
+            cardholder_name: card
+                .card_holder_name
+                .clone()
+                .ok_or_else(utils::missing_field_err("card_holder_name"))?,
             card_pan: card.card_number.clone(),
             card_expiration: card.get_expiry_date_as_yymm(),
             card_cvv: card.card_cvc.clone(),
         };
-        Self::Card(card)
+        Ok(Self::Card(card))
     }
 }
 
diff --git a/crates/router/src/connector/rapyd/transformers.rs b/crates/router/src/connector/rapyd/transformers.rs
index 193eb819892..aab47bc8b21 100644
--- a/crates/router/src/connector/rapyd/transformers.rs
+++ b/crates/router/src/connector/rapyd/transformers.rs
@@ -4,7 +4,7 @@ use time::PrimitiveDateTime;
 use url::Url;
 
 use crate::{
-    connector::utils::PaymentsAuthorizeRequestData,
+    connector::utils::{self, PaymentsAuthorizeRequestData},
     consts,
     core::errors,
     pii::Secret,
@@ -131,7 +131,10 @@ impl TryFrom<&RapydRouterData<&types::PaymentsAuthorizeRouterData>> for RapydPay
                         number: ccard.card_number.to_owned(),
                         expiration_month: ccard.card_exp_month.to_owned(),
                         expiration_year: ccard.card_exp_year.to_owned(),
-                        name: ccard.card_holder_name.to_owned(),
+                        name: ccard
+                            .card_holder_name
+                            .to_owned()
+                            .ok_or_else(utils::missing_field_err("card_holder_name"))?,
                         cvv: ccard.card_cvc.to_owned(),
                     }),
                     address: None,
diff --git a/crates/router/src/connector/shift4/transformers.rs b/crates/router/src/connector/shift4/transformers.rs
index ce68aad25c5..2b89e7ebf6c 100644
--- a/crates/router/src/connector/shift4/transformers.rs
+++ b/crates/router/src/connector/shift4/transformers.rs
@@ -296,7 +296,10 @@ impl<T>
             number: card.card_number.clone(),
             exp_month: card.card_exp_month.clone(),
             exp_year: card.card_exp_year.clone(),
-            cardholder_name: card.card_holder_name.clone(),
+            cardholder_name: card
+                .card_holder_name
+                .clone()
+                .ok_or_else(utils::missing_field_err("card_holder_name"))?,
         };
         if item.is_three_ds() {
             Ok(Self::Cards3DSRequest(Box::new(Cards3DSRequest {
diff --git a/crates/router/src/connector/stax/transformers.rs b/crates/router/src/connector/stax/transformers.rs
index 2fd3b3474ea..7395172239e 100644
--- a/crates/router/src/connector/stax/transformers.rs
+++ b/crates/router/src/connector/stax/transformers.rs
@@ -226,7 +226,9 @@ impl TryFrom<&types::TokenizationRouterData> for StaxTokenRequest {
                 let stax_card_data = StaxTokenizeData {
                     card_exp: card_data
                         .get_card_expiry_month_year_2_digit_with_delimiter("".to_string()),
-                    person_name: card_data.card_holder_name,
+                    person_name: card_data
+                        .card_holder_name
+                        .ok_or_else(missing_field_err("card_holder_name"))?,
                     card_number: card_data.card_number,
                     card_cvv: card_data.card_cvc,
                     customer_id: Secret::new(customer_id),
diff --git a/crates/router/src/connector/worldline/transformers.rs b/crates/router/src/connector/worldline/transformers.rs
index b5739fe857a..d9e9d1ff7c0 100644
--- a/crates/router/src/connector/worldline/transformers.rs
+++ b/crates/router/src/connector/worldline/transformers.rs
@@ -351,7 +351,10 @@ fn make_card_request(
     let expiry_date: Secret<String> = Secret::new(secret_value);
     let card = Card {
         card_number: ccard.card_number.clone(),
-        cardholder_name: ccard.card_holder_name.clone(),
+        cardholder_name: ccard
+            .card_holder_name
+            .clone()
+            .ok_or_else(utils::missing_field_err("card_holder_name"))?,
         cvv: ccard.card_cvc.clone(),
         expiry_date,
     };
diff --git a/crates/router/src/core/payment_methods/vault.rs b/crates/router/src/core/payment_methods/vault.rs
index 5ad78c9d730..c71632c9b06 100644
--- a/crates/router/src/core/payment_methods/vault.rs
+++ b/crates/router/src/core/payment_methods/vault.rs
@@ -51,7 +51,10 @@ impl Vaultable for api::Card {
             card_number: self.card_number.peek().clone(),
             exp_year: self.card_exp_year.peek().clone(),
             exp_month: self.card_exp_month.peek().clone(),
-            name_on_card: Some(self.card_holder_name.peek().clone()),
+            name_on_card: self
+                .card_holder_name
+                .clone()
+                .map(|name| name.peek().clone()),
             nickname: None,
             card_last_four: None,
             card_token: None,
@@ -99,7 +102,7 @@ impl Vaultable for api::Card {
                 .attach_printable("Invalid card number format from the mock locker")?,
             card_exp_month: value1.exp_month.into(),
             card_exp_year: value1.exp_year.into(),
-            card_holder_name: value1.name_on_card.unwrap_or_default().into(),
+            card_holder_name: value1.name_on_card.map(masking::Secret::new),
             card_cvc: value2.card_security_code.unwrap_or_default().into(),
             card_issuer: None,
             card_network: None,
diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs
index 4e491964e96..866a0581e4e 100644
--- a/crates/router/src/core/payments/helpers.rs
+++ b/crates/router/src/core/payments/helpers.rs
@@ -946,6 +946,42 @@ pub fn verify_mandate_details(
     )
 }
 
+// This function validates card_holder_name field to be either null or a non-empty string
+pub fn validate_card_holder_name(
+    payment_method_data: Option<api::PaymentMethodData>,
+) -> CustomResult<(), errors::ApiErrorResponse> {
+    if let Some(pmd) = payment_method_data {
+        match pmd {
+            // This validation would occur during payments create
+            api::PaymentMethodData::Card(card) => {
+                if let Some(name) = &card.card_holder_name {
+                    if name.clone().expose().is_empty() {
+                        return Err(errors::ApiErrorResponse::InvalidRequestData {
+                            message: "card_holder_name cannot be empty".to_string(),
+                        })
+                        .into_report();
+                    }
+                }
+            }
+
+            // This validation would occur during payments confirm
+            api::PaymentMethodData::CardToken(card) => {
+                if let Some(name) = card.card_holder_name {
+                    if name.expose().is_empty() {
+                        return Err(errors::ApiErrorResponse::InvalidRequestData {
+                            message: "card_holder_name cannot be empty".to_string(),
+                        })
+                        .into_report();
+                    }
+                }
+            }
+            _ => (),
+        }
+    }
+
+    Ok(())
+}
+
 #[instrument(skip_all)]
 pub fn payment_attempt_status_fsm(
     payment_method_data: &Option<api::PaymentMethodData>,
@@ -1033,7 +1069,7 @@ pub(crate) async fn get_payment_method_create_request(
                         card_number: card.card_number.clone(),
                         card_exp_month: card.card_exp_month.clone(),
                         card_exp_year: card.card_exp_year.clone(),
-                        card_holder_name: Some(card.card_holder_name.clone()),
+                        card_holder_name: card.card_holder_name.clone(),
                         nick_name: card.nick_name.clone(),
                     };
                     let customer_id = customer.customer_id.clone();
@@ -1404,21 +1440,25 @@ pub async fn retrieve_payment_method_with_temporary_token(
             let mut updated_card = card.clone();
             let mut is_card_updated = false;
 
-            let name_on_card = if card.card_holder_name.clone().expose().is_empty() {
-                card_token_data
-                    .and_then(|token_data| token_data.card_holder_name.clone())
-                    .filter(|name_on_card| !name_on_card.clone().expose().is_empty())
-                    .map(|name_on_card| {
+            // 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.card_token object
+            let name_on_card = if let Some(name) = card.card_holder_name.clone() {
+                if name.expose().is_empty() {
+                    card_token_data.and_then(|token_data| {
                         is_card_updated = true;
-                        name_on_card
+                        token_data.card_holder_name.clone()
                     })
+                } else {
+                    card.card_holder_name.clone()
+                }
             } else {
-                Some(card.card_holder_name.clone())
+                card_token_data.and_then(|token_data| {
+                    is_card_updated = true;
+                    token_data.card_holder_name.clone()
+                })
             };
 
-            if let Some(name_on_card) = name_on_card {
-                updated_card.card_holder_name = name_on_card;
-            }
+            updated_card.card_holder_name = name_on_card;
 
             if let Some(token_data) = card_token_data {
                 if let Some(cvc) = token_data.card_cvc.clone() {
@@ -1487,23 +1527,21 @@ pub async fn retrieve_card_with_permanent_token(
         .change_context(errors::ApiErrorResponse::InternalServerError)
         .attach_printable("failed to fetch card information from the permanent locker")?;
 
-    let name_on_card = if let Some(name_on_card) = card.name_on_card.clone() {
-        if card.name_on_card.unwrap_or_default().expose().is_empty() {
-            card_token_data
-                .and_then(|token_data| token_data.card_holder_name.clone())
-                .filter(|name_on_card| !name_on_card.clone().expose().is_empty())
+    // 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.card_token object
+    let name_on_card = if let Some(name) = card.name_on_card.clone() {
+        if name.expose().is_empty() {
+            card_token_data.and_then(|token_data| token_data.card_holder_name.clone())
         } else {
-            Some(name_on_card)
+            card.name_on_card
         }
     } else {
-        card_token_data
-            .and_then(|token_data| token_data.card_holder_name.clone())
-            .filter(|name_on_card| !name_on_card.clone().expose().is_empty())
+        card_token_data.and_then(|token_data| token_data.card_holder_name.clone())
     };
 
     let api_card = api::Card {
         card_number: card.card_number,
-        card_holder_name: name_on_card.unwrap_or(masking::Secret::from("".to_string())),
+        card_holder_name: name_on_card,
         card_exp_month: card.card_exp_month,
         card_exp_year: card.card_exp_year,
         card_cvc: card_token_data
@@ -3324,7 +3362,7 @@ pub async fn get_additional_payment_data(
                         bank_code: card_data.bank_code.to_owned(),
                         card_exp_month: Some(card_data.card_exp_month.clone()),
                         card_exp_year: Some(card_data.card_exp_year.clone()),
-                        card_holder_name: Some(card_data.card_holder_name.clone()),
+                        card_holder_name: card_data.card_holder_name.clone(),
                         last4: last4.clone(),
                         card_isin: card_isin.clone(),
                     },
@@ -3352,7 +3390,7 @@ pub async fn get_additional_payment_data(
                                 card_isin: card_isin.clone(),
                                 card_exp_month: Some(card_data.card_exp_month.clone()),
                                 card_exp_year: Some(card_data.card_exp_year.clone()),
-                                card_holder_name: Some(card_data.card_holder_name.clone()),
+                                card_holder_name: card_data.card_holder_name.clone(),
                             },
                         ))
                     });
@@ -3367,7 +3405,7 @@ pub async fn get_additional_payment_data(
                         card_isin,
                         card_exp_month: Some(card_data.card_exp_month.clone()),
                         card_exp_year: Some(card_data.card_exp_year.clone()),
-                        card_holder_name: Some(card_data.card_holder_name.clone()),
+                        card_holder_name: card_data.card_holder_name.clone(),
                     },
                 )))
             }
diff --git a/crates/router/src/core/payments/operations/payment_confirm.rs b/crates/router/src/core/payments/operations/payment_confirm.rs
index af2a9fa49c8..612ddadc1c5 100644
--- a/crates/router/src/core/payments/operations/payment_confirm.rs
+++ b/crates/router/src/core/payments/operations/payment_confirm.rs
@@ -871,6 +871,8 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve> ValidateRequest<F, api::Paymen
 
         helpers::validate_payment_method_fields_present(request)?;
 
+        helpers::validate_card_holder_name(request.payment_method_data.clone())?;
+
         let mandate_type =
             helpers::validate_mandate(request, payments::is_operation_confirm(self))?;
 
diff --git a/crates/router/src/core/payments/operations/payment_create.rs b/crates/router/src/core/payments/operations/payment_create.rs
index eb7f31ba24d..cbce6ba9e97 100644
--- a/crates/router/src/core/payments/operations/payment_create.rs
+++ b/crates/router/src/core/payments/operations/payment_create.rs
@@ -560,6 +560,8 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve> ValidateRequest<F, api::Paymen
         helpers::validate_amount_to_capture_and_capture_method(None, request)?;
         helpers::validate_card_data(request.payment_method_data.clone())?;
 
+        helpers::validate_card_holder_name(request.payment_method_data.clone())?;
+
         helpers::validate_payment_method_fields_present(request)?;
 
         let mandate_type =
diff --git a/crates/router/src/core/payments/operations/payment_update.rs b/crates/router/src/core/payments/operations/payment_update.rs
index f1a35cffce8..84f11124c73 100644
--- a/crates/router/src/core/payments/operations/payment_update.rs
+++ b/crates/router/src/core/payments/operations/payment_update.rs
@@ -655,6 +655,8 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve> ValidateRequest<F, api::Paymen
 
         helpers::validate_payment_method_fields_present(request)?;
 
+        helpers::validate_card_holder_name(request.payment_method_data.clone())?;
+
         let mandate_type = helpers::validate_mandate(request, false)?;
 
         Ok((
diff --git a/crates/router/src/types/api/payments.rs b/crates/router/src/types/api/payments.rs
index 2acf42fa479..9159abf4bd1 100644
--- a/crates/router/src/types/api/payments.rs
+++ b/crates/router/src/types/api/payments.rs
@@ -244,7 +244,7 @@ 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: "JohnDoe".to_string().into(),
+            card_holder_name: Some(masking::Secret::new("JohnDoe".to_string())),
             card_cvc: "123".to_string().into(),
             card_issuer: Some("HDFC".to_string()),
             card_network: Some(api_models::enums::CardNetwork::Visa),
diff --git a/crates/router/src/utils/verify_connector.rs b/crates/router/src/utils/verify_connector.rs
index 6ad683d63ba..060f92d0e5a 100644
--- a/crates/router/src/utils/verify_connector.rs
+++ b/crates/router/src/utils/verify_connector.rs
@@ -20,7 +20,7 @@ pub fn generate_card_from_details(
         card_network: None,
         card_exp_year: masking::Secret::new(card_exp_year),
         card_exp_month: masking::Secret::new(card_exp_month),
-        card_holder_name: masking::Secret::new("HyperSwitch".to_string()),
+        card_holder_name: Some(masking::Secret::new("HyperSwitch".to_string())),
         nick_name: None,
         card_type: None,
         card_issuing_country: None,
diff --git a/crates/router/tests/connectors/aci.rs b/crates/router/tests/connectors/aci.rs
index 7ddc504956f..dd8c1ed5f77 100644
--- a/crates/router/tests/connectors/aci.rs
+++ b/crates/router/tests/connectors/aci.rs
@@ -38,7 +38,7 @@ fn construct_payment_router_data() -> types::PaymentsAuthorizeRouterData {
                 card_number: cards::CardNumber::from_str("4200000000000000").unwrap(),
                 card_exp_month: Secret::new("10".to_string()),
                 card_exp_year: Secret::new("2025".to_string()),
-                card_holder_name: Secret::new("John Doe".to_string()),
+                card_holder_name: Some(masking::Secret::new("John Doe".to_string())),
                 card_cvc: Secret::new("999".to_string()),
                 card_issuer: None,
                 card_network: None,
@@ -232,7 +232,7 @@ async fn payments_create_failure() {
                 card_number: cards::CardNumber::from_str("4200000000000000").unwrap(),
                 card_exp_month: Secret::new("10".to_string()),
                 card_exp_year: Secret::new("2025".to_string()),
-                card_holder_name: Secret::new("John Doe".to_string()),
+                card_holder_name: Some(masking::Secret::new("John Doe".to_string())),
                 card_cvc: Secret::new("99".to_string()),
                 card_issuer: None,
                 card_network: None,
diff --git a/crates/router/tests/connectors/adyen.rs b/crates/router/tests/connectors/adyen.rs
index 714dc0d7d67..14177e6fb50 100644
--- a/crates/router/tests/connectors/adyen.rs
+++ b/crates/router/tests/connectors/adyen.rs
@@ -126,7 +126,7 @@ impl AdyenTest {
                 card_number: cards::CardNumber::from_str(card_number).unwrap(),
                 card_exp_month: Secret::new(card_exp_month.to_string()),
                 card_exp_year: Secret::new(card_exp_year.to_string()),
-                card_holder_name: Secret::new("John Doe".to_string()),
+                card_holder_name: Some(masking::Secret::new("John Doe".to_string())),
                 card_cvc: Secret::new(card_cvc.to_string()),
                 card_issuer: None,
                 card_network: None,
diff --git a/crates/router/tests/connectors/airwallex.rs b/crates/router/tests/connectors/airwallex.rs
index 6e7f6c000d2..cfc4c0c003d 100644
--- a/crates/router/tests/connectors/airwallex.rs
+++ b/crates/router/tests/connectors/airwallex.rs
@@ -60,7 +60,7 @@ fn payment_method_details() -> Option<types::PaymentsAuthorizeData> {
             card_number: cards::CardNumber::from_str("4035501000000008").unwrap(),
             card_exp_month: Secret::new("02".to_string()),
             card_exp_year: Secret::new("2035".to_string()),
-            card_holder_name: Secret::new("John Doe".to_string()),
+            card_holder_name: Some(masking::Secret::new("John Doe".to_string())),
             card_cvc: Secret::new("123".to_string()),
             card_issuer: None,
             card_network: None,
diff --git a/crates/router/tests/connectors/authorizedotnet.rs b/crates/router/tests/connectors/authorizedotnet.rs
index 4021d57d543..3ae4298e836 100644
--- a/crates/router/tests/connectors/authorizedotnet.rs
+++ b/crates/router/tests/connectors/authorizedotnet.rs
@@ -42,7 +42,7 @@ fn get_payment_method_data() -> api::Card {
         card_number: cards::CardNumber::from_str("5424000000000015").unwrap(),
         card_exp_month: Secret::new("02".to_string()),
         card_exp_year: Secret::new("2035".to_string()),
-        card_holder_name: Secret::new("John Doe".to_string()),
+        card_holder_name: Some(masking::Secret::new("John Doe".to_string())),
         card_cvc: Secret::new("123".to_string()),
         ..Default::default()
     }
diff --git a/crates/router/tests/connectors/bluesnap.rs b/crates/router/tests/connectors/bluesnap.rs
index 30052d11da4..852b23f022c 100644
--- a/crates/router/tests/connectors/bluesnap.rs
+++ b/crates/router/tests/connectors/bluesnap.rs
@@ -400,7 +400,7 @@ async fn should_fail_payment_for_incorrect_cvc() {
             Some(types::PaymentsAuthorizeData {
                 email: Some(Email::from_str("test@gmail.com").unwrap()),
                 payment_method_data: types::api::PaymentMethodData::Card(api::Card {
-                    card_holder_name: Secret::new("John Doe".to_string()),
+                    card_holder_name: Some(masking::Secret::new("John Doe".to_string())),
                     card_cvc: Secret::new("12345".to_string()),
                     ..utils::CCardType::default().0
                 }),
@@ -426,7 +426,7 @@ async fn should_fail_payment_for_invalid_exp_month() {
             Some(types::PaymentsAuthorizeData {
                 email: Some(Email::from_str("test@gmail.com").unwrap()),
                 payment_method_data: types::api::PaymentMethodData::Card(api::Card {
-                    card_holder_name: Secret::new("John Doe".to_string()),
+                    card_holder_name: Some(masking::Secret::new("John Doe".to_string())),
                     card_exp_month: Secret::new("20".to_string()),
                     ..utils::CCardType::default().0
                 }),
@@ -452,7 +452,7 @@ async fn should_fail_payment_for_incorrect_expiry_year() {
             Some(types::PaymentsAuthorizeData {
                 email: Some(Email::from_str("test@gmail.com").unwrap()),
                 payment_method_data: types::api::PaymentMethodData::Card(api::Card {
-                    card_holder_name: Secret::new("John Doe".to_string()),
+                    card_holder_name: Some(masking::Secret::new("John Doe".to_string())),
                     card_exp_year: Secret::new("2000".to_string()),
                     ..utils::CCardType::default().0
                 }),
diff --git a/crates/router/tests/connectors/fiserv.rs b/crates/router/tests/connectors/fiserv.rs
index 1394667718c..36d5f66dbcc 100644
--- a/crates/router/tests/connectors/fiserv.rs
+++ b/crates/router/tests/connectors/fiserv.rs
@@ -46,7 +46,7 @@ fn payment_method_details() -> Option<types::PaymentsAuthorizeData> {
             card_number: cards::CardNumber::from_str("4005550000000019").unwrap(),
             card_exp_month: Secret::new("02".to_string()),
             card_exp_year: Secret::new("2035".to_string()),
-            card_holder_name: Secret::new("John Doe".to_string()),
+            card_holder_name: Some(masking::Secret::new("John Doe".to_string())),
             card_cvc: Secret::new("123".to_string()),
             card_issuer: None,
             card_network: None,
diff --git a/crates/router/tests/connectors/payme.rs b/crates/router/tests/connectors/payme.rs
index 5550ba12af8..7de81a8bed2 100644
--- a/crates/router/tests/connectors/payme.rs
+++ b/crates/router/tests/connectors/payme.rs
@@ -87,7 +87,7 @@ fn payment_method_details() -> Option<types::PaymentsAuthorizeData> {
             card_cvc: Secret::new("123".to_string()),
             card_exp_month: Secret::new("10".to_string()),
             card_exp_year: Secret::new("2025".to_string()),
-            card_holder_name: Secret::new("John Doe".to_string()),
+            card_holder_name: Some(masking::Secret::new("John Doe".to_string())),
             ..utils::CCardType::default().0
         }),
         amount: 1000,
diff --git a/crates/router/tests/connectors/rapyd.rs b/crates/router/tests/connectors/rapyd.rs
index 143f87fc575..c53f4e8d8b1 100644
--- a/crates/router/tests/connectors/rapyd.rs
+++ b/crates/router/tests/connectors/rapyd.rs
@@ -46,7 +46,7 @@ async fn should_only_authorize_payment() {
                     card_number: cards::CardNumber::from_str("4111111111111111").unwrap(),
                     card_exp_month: Secret::new("02".to_string()),
                     card_exp_year: Secret::new("2024".to_string()),
-                    card_holder_name: Secret::new("John Doe".to_string()),
+                    card_holder_name: Some(masking::Secret::new("John Doe".to_string())),
                     card_cvc: Secret::new("123".to_string()),
                     card_issuer: None,
                     card_network: None,
@@ -74,7 +74,7 @@ async fn should_authorize_and_capture_payment() {
                     card_number: cards::CardNumber::from_str("4111111111111111").unwrap(),
                     card_exp_month: Secret::new("02".to_string()),
                     card_exp_year: Secret::new("2024".to_string()),
-                    card_holder_name: Secret::new("John Doe".to_string()),
+                    card_holder_name: Some(masking::Secret::new("John Doe".to_string())),
                     card_cvc: Secret::new("123".to_string()),
                     card_issuer: None,
                     card_network: None,
diff --git a/crates/router/tests/connectors/utils.rs b/crates/router/tests/connectors/utils.rs
index 7e5cfeb4397..d3b20b01e4c 100644
--- a/crates/router/tests/connectors/utils.rs
+++ b/crates/router/tests/connectors/utils.rs
@@ -869,7 +869,7 @@ impl Default for CCardType {
             card_number: cards::CardNumber::from_str("4200000000000000").unwrap(),
             card_exp_month: Secret::new("10".to_string()),
             card_exp_year: Secret::new("2025".to_string()),
-            card_holder_name: Secret::new("John Doe".to_string()),
+            card_holder_name: Some(masking::Secret::new("John Doe".to_string())),
             card_cvc: Secret::new("999".to_string()),
             card_issuer: None,
             card_network: None,
diff --git a/crates/router/tests/connectors/worldline.rs b/crates/router/tests/connectors/worldline.rs
index fd697f95b75..6a92e0dc93f 100644
--- a/crates/router/tests/connectors/worldline.rs
+++ b/crates/router/tests/connectors/worldline.rs
@@ -71,7 +71,7 @@ impl WorldlineTest {
                 card_number: cards::CardNumber::from_str(card_number).unwrap(),
                 card_exp_month: Secret::new(card_exp_month.to_string()),
                 card_exp_year: Secret::new(card_exp_year.to_string()),
-                card_holder_name: Secret::new("John Doe".to_string()),
+                card_holder_name: Some(masking::Secret::new("John Doe".to_string())),
                 card_cvc: Secret::new(card_cvc.to_string()),
                 card_issuer: None,
                 card_network: None,
diff --git a/crates/router/tests/payments.rs b/crates/router/tests/payments.rs
index 9d48aaddd45..8f5ac25736c 100644
--- a/crates/router/tests/payments.rs
+++ b/crates/router/tests/payments.rs
@@ -320,7 +320,7 @@ 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: "Arun Raj".to_string().into(),
+            card_holder_name: Some(masking::Secret::new("Arun Raj".to_string())),
             card_cvc: "123".to_string().into(),
             card_issuer: None,
             card_network: None,
@@ -496,7 +496,7 @@ 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: "JohnDoe".to_string().into(),
+            card_holder_name: Some(masking::Secret::new("JohnDoe".to_string())),
             card_cvc: "737".to_string().into(),
             card_issuer: None,
             card_network: None,
diff --git a/crates/router/tests/payments2.rs b/crates/router/tests/payments2.rs
index 42e5524a15d..89ac522d237 100644
--- a/crates/router/tests/payments2.rs
+++ b/crates/router/tests/payments2.rs
@@ -80,7 +80,7 @@ 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: "Arun Raj".to_string().into(),
+            card_holder_name: Some(masking::Secret::new("Arun Raj".to_string())),
             card_cvc: "123".to_string().into(),
             card_issuer: None,
             card_network: None,
@@ -263,7 +263,7 @@ 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: "JohnDoe".to_string().into(),
+            card_holder_name: Some(masking::Secret::new("JohnDoe".to_string())),
             card_cvc: "737".to_string().into(),
             bank_code: None,
             card_issuer: None,

## Type of Change
<!-- Put an `x` in the boxes that apply -->

- [ ] Bugfix
- [ ] New feature
- [ ] Enhancement
- [x] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD

## Description
<!-- Describe your changes in detail -->
We currently have the `card_holder_name` as mandatory for cards in the payment APIs. We currently do not mandatorily collect it for every payment so this causes the SDK to have to send an empty string for payments where the card holder name is not collected. 
This PR includes following changes:
* Refactoring to allow `card_holder_name` field for null values to avoid the need to send empty strings for the SDK.
* Throw error when `card_holder_name` is not passed for the connector in which `card_holder_name` is a required field.
* Allow sending either `null` or `non-empty string` for `card_holder_name` field. If an empty string is passed, throws an error

Above changes apply during both payments `create` and `confirm`
### Additional Changes

- [x] This PR modifies the API contract
- [ ] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables

<!--
Provide links to the files with corresponding changes.

Following are the paths where you can find config files:
1. `config`
2. `crates/router/src/configs`
3. `loadtest/config`
-->


## Motivation and Context
<!--
Why is this change required? What problem does it solve?
If it fixes an open issue, please link to the issue here.

If you don't have an issue, we'd recommend starting with one first so the PR
can focus on the implementation (unless it is an obvious bug or documentation fix
that will have little conversation).
-->


## How did you test it?
<!--
Did you write an integration/unit/API test to verify the code changes?
Or did you test this change manually (provide relevant screenshots)?
-->
1. Create merchant account
```
curl --location 'http://localhost:8080/accounts' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: test_admin' \
--data-raw '{
  "merchant_id": "merchant_1701880995",
  "locker_id": "m0010",
  "merchant_name": "Chethan",
  "merchant_details": {
    "primary_contact_person": "John Test",
    "primary_email": "JohnTest@test.com",
    "primary_phone": "sunt laborum",
    "secondary_contact_person": "John Test2",
    "secondary_email": "JohnTest2@test.com",
    "secondary_phone": "cillum do dolor id",
    "website": "www.example.com",
    "about_business": "Online Retail with a wide selection of organic products for North America",
    "address": {
      "line1": "1467",
      "line2": "Harrison Street",
      "line3": "Harrison Street",
      "city": "San Fransico",
      "state": "California",
      "zip": "94122",
      "country": "US"
    }
  },
  "return_url": "https://google.com/success",
  "webhook_details": {
     "webhook_username": "ekart_retail",
    "webhook_password": "password_ekart@123",
    "payment_created_enabled": true,
    "payment_succeeded_enabled": true,
    "payment_failed_enabled": true
  },
  "sub_merchants_enabled": false,
  "metadata": {
    "city": "NY",
    "unit": "245"
  },
  "primary_business_details": [
    {
      "country": "US",
      "business": "default"
    }
  ]
}'
```

2. Create API key
```
curl --location 'http://localhost:8080/api_keys/merchant_1701880168' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: test_admin' \
--data '{
  "name": "API Key 1",
  "description": null,
  "expiration": "2024-07-06T06:15:00.000Z"
}'
```

3. Create MCA account with ACI as connector (because `card_holder_name` is required field for ACI)
```
curl --location 'http://localhost:8080/account/merchant_1701880168/connectors' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: test_admin' \
--data '{
    "connector_type": "fiz_operations",
    "connector_name": "aci",
    "connector_account_details": {
        "api_key": "Bearer OGFjN2E0Yzk3ZDA0NDMwNTAxN2QwNTMxNDQxMjA5ZjF8emV6N1lTUHNEaw==",
        "auth_type": "BodyKey",
        "key1": "8ac7a4c97d044305017d053142b009ed"
    },
    "test_mode": false,
    "disabled": false,
    "payment_methods_enabled": [
        {
            "payment_method": "card",
            "payment_method_types": [
                {
                    "payment_method_type": "credit",
                    "card_networks": [
                        "Visa",
                        "Mastercard"
                    ],
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true
                },
                {
                    "payment_method_type": "debit",
                    "card_networks": [
                        "Visa",
                        "Mastercard"
                    ],
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true
                }
            ]
        },
        {
            "payment_method": "wallet",
            "payment_method_types": [
                {
                    "payment_method_type": "ali_pay",
                    "payment_experience": "invoke_sdk_client",
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true
                },
                {
                    "payment_method_type": "mb_way",
                    "payment_experience": "invoke_sdk_client",
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true
                }
            ]
        },
        {
        "payment_method": "bank_redirect",
        "payment_method_types": [
            {
                "payment_method_type": "interac",
                "payment_experience": "redirect_to_url",
                "minimum_amount": 1,
                "maximum_amount": 68607706,
                "recurring_enabled": true,
                "installment_payment_enabled": true

            }
        ]
    }
    ],
    "metadata": {
        "city": "NY",
        "unit": "245"
    }
}'
```

4. Make a payment without passing `card_holder_name` 
```
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_dk7ZaxtZSxglnD4CUK3R2mPZBfOczCfAytnTyZZ0gm2u5sJqLyo4w5CiEJLIRT5e' \
--data-raw '{
    "amount": 6540,
    "currency": "USD",
    "confirm": true,
    "capture_method": "automatic",
    "capture_on": "2022-09-10T10:11:12Z",
    "amount_to_capture": 6540,
    "customer_id": "StripeCustomer",
    "business_country": "US",
    "business_label": "default",
    "email": "guest@example.com",
    "name": "John Doe",
    "phone": "999999999",
    "phone_country_code": "+1",
    "description": "Its my first payment request",
    "authentication_type": "no_three_ds",
    "return_url": "https://google.com",
    "payment_method": "card",
    "payment_method_type": "credit",
    "setup_future_usage": "on_session",
    "payment_method_data": {
        "card": {
            "card_number": "4242424242424242",
            "card_exp_month": "10",
            "card_exp_year": "25",
            "card_cvc": "123"
        }
    },
    "shipping": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594430",
            "country_code": "+91"
        }
    },
    "billing": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        }
    },
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    }
}'
```

Above API should throw below error 

![error](https://github.com/juspay/hyperswitch/assets/70657455/4b38f4d1-3623-4971-9673-cd19737b22fd)

5. You can check this flow for connector in which  `card_holder_name` is not a required field (like stripe). In this case you need not pass the `card_holder_name` as it is made optional here.

6. If u try to make a payment with `card_holder_name` empty, it will throw below error
```
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_98wh5QexR03yFlBCDPr0eSkvWH69UB1DwpSQyGK9qBSMPTeo2vWBmD0D3yAHdl54' \
--data-raw '{
    "amount": 6540,
    "currency": "USD",
    "confirm": true,
    "capture_method": "automatic",
    "capture_on": "2022-09-10T10:11:12Z",
    "amount_to_capture": 6540,
    "customer_id": "StripeCustomer",
    "business_country": "US",
    "business_label": "default",
    "email": "guest@example.com",
    "name": "John Doe",
    "phone": "999999999",
    "phone_country_code": "+1",
    "description": "Its my first payment request",
    "authentication_type": "no_three_ds",
    "return_url": "https://google.com",
    "payment_method": "card",
    "payment_method_type": "credit",
    "payment_method_data": {
        "card": {
            "card_number": "4242424242424242",
            "card_exp_month": "10",
            "card_exp_year": "25",
            "card_cvc": "123",
            "card_holder_name": ""
        }
    },
    "shipping": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594430",
            "country_code": "+91"
        }
    },
    "billing": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        }
    },
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    }
}'
```

![image](https://github.com/juspay/hyperswitch/assets/70657455/4fc50540-8e67-4d8a-a52d-0b5c4aff1786)

7. You can try above flow with `/confirm` route too
```
curl --location 'http://localhost:8080/payments/pay_QXQSt3xFUpR1DRWWkCwW/confirm' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_98wh5QexR03yFlBCDPr0eSkvWH69UB1DwpSQyGK9qBSMPTeo2vWBmD0D3yAHdl54' \
--data '{
    "payment_method": "card",
    "payment_method_type": "credit",
    "payment_token": "token_WuamozY38qmQBbPXn7aS",
    "payment_method_data": {
        "card_token": {
            "card_holder_name": ""
        }
    }
}'
```

## Checklist
<!-- Put an `x` in the boxes that apply -->

- [x] I formatted the code `cargo +nightly fmt --all`
- [x] I addressed lints thrown by `cargo clippy`
- [x] I reviewed the submitted code
- [ ] I added unit tests for my changes where possible
- [ ] I added a [CHANGELOG](/CHANGELOG.md) entry if applicable
