mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-11-01 02:57:02 +08:00 
			
		
		
		
	feat(payment_methods): receive card_holder_name in confirm flow when using token for payment (#2982)
				
					
				
			Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
		| @ -1,6 +1,6 @@ | ||||
| use std::borrow::Cow; | ||||
|  | ||||
| use api_models::payments::GetPaymentMethodType; | ||||
| use api_models::payments::{CardToken, GetPaymentMethodType}; | ||||
| use base64::Engine; | ||||
| use common_utils::{ | ||||
|     ext_traits::{AsyncExt, ByteSliceExt, ValueExt}, | ||||
| @ -1356,6 +1356,7 @@ pub async fn retrieve_payment_method_with_temporary_token( | ||||
|     payment_intent: &PaymentIntent, | ||||
|     card_cvc: Option<masking::Secret<String>>, | ||||
|     merchant_key_store: &domain::MerchantKeyStore, | ||||
|     card_token_data: Option<&CardToken>, | ||||
| ) -> RouterResult<Option<(api::PaymentMethodData, enums::PaymentMethod)>> { | ||||
|     let (pm, supplementary_data) = | ||||
|         vault::Vault::get_payment_method_data_from_locker(state, token, merchant_key_store) | ||||
| @ -1375,9 +1376,29 @@ pub async fn retrieve_payment_method_with_temporary_token( | ||||
|  | ||||
|     Ok::<_, error_stack::Report<errors::ApiErrorResponse>>(match pm { | ||||
|         Some(api::PaymentMethodData::Card(card)) => { | ||||
|             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| { | ||||
|                         is_card_updated = true; | ||||
|                         token_data.card_holder_name.clone() | ||||
|                     }) | ||||
|                     .filter(|name_on_card| !name_on_card.clone().expose().is_empty()) | ||||
|                     .ok_or(errors::ApiErrorResponse::MissingRequiredField { | ||||
|                         field_name: "card_holder_name", | ||||
|                     })? | ||||
|             } else { | ||||
|                 card.card_holder_name.clone() | ||||
|             }; | ||||
|             updated_card.card_holder_name = name_on_card; | ||||
|  | ||||
|             if let Some(cvc) = card_cvc { | ||||
|                 let mut updated_card = card; | ||||
|                 is_card_updated = true; | ||||
|                 updated_card.card_cvc = cvc; | ||||
|             } | ||||
|             if is_card_updated { | ||||
|                 let updated_pm = api::PaymentMethodData::Card(updated_card); | ||||
|                 vault::Vault::store_payment_method_data_in_locker( | ||||
|                     state, | ||||
| @ -1423,6 +1444,7 @@ pub async fn retrieve_card_with_permanent_token( | ||||
|     token: &str, | ||||
|     payment_intent: &PaymentIntent, | ||||
|     card_cvc: Option<masking::Secret<String>>, | ||||
|     card_token_data: Option<&CardToken>, | ||||
| ) -> RouterResult<api::PaymentMethodData> { | ||||
|     let customer_id = payment_intent | ||||
|         .customer_id | ||||
| @ -1437,13 +1459,26 @@ 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 = card | ||||
|         .name_on_card | ||||
|         .get_required_value("name_on_card") | ||||
|         .change_context(errors::ApiErrorResponse::InternalServerError) | ||||
|         .attach_printable("card holder name was not saved in permanent locker")?; | ||||
|  | ||||
|     let name_on_card = if 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()) | ||||
|             .ok_or(errors::ApiErrorResponse::MissingRequiredField { | ||||
|                 field_name: "card_holder_name", | ||||
|             })? | ||||
|     } else { | ||||
|         name | ||||
|     }; | ||||
|  | ||||
|     let api_card = api::Card { | ||||
|         card_number: card.card_number, | ||||
|         card_holder_name: card | ||||
|             .name_on_card | ||||
|             .get_required_value("name_on_card") | ||||
|             .change_context(errors::ApiErrorResponse::InternalServerError) | ||||
|             .attach_printable("card holder name was not saved in permanent locker")?, | ||||
|         card_holder_name: name_on_card, | ||||
|         card_exp_month: card.card_exp_month, | ||||
|         card_exp_year: card.card_exp_year, | ||||
|         card_cvc: card_cvc.unwrap_or_default(), | ||||
| @ -1529,6 +1564,11 @@ pub async fn make_pm_data<'a, F: Clone, R, Ctx: PaymentMethodRetrieve>( | ||||
|  | ||||
|     let card_cvc = payment_data.card_cvc.clone(); | ||||
|  | ||||
|     let card_token_data = request.as_ref().and_then(|pmd| match pmd { | ||||
|         api_models::payments::PaymentMethodData::CardToken(token_data) => Some(token_data), | ||||
|         _ => None, | ||||
|     }); | ||||
|  | ||||
|     // TODO: Handle case where payment method and token both are present in request properly. | ||||
|     let payment_method = match (request, hyperswitch_token) { | ||||
|         (_, Some(hyperswitch_token)) => { | ||||
| @ -1538,6 +1578,7 @@ pub async fn make_pm_data<'a, F: Clone, R, Ctx: PaymentMethodRetrieve>( | ||||
|                 &hyperswitch_token, | ||||
|                 &payment_data.payment_intent, | ||||
|                 card_cvc, | ||||
|                 card_token_data, | ||||
|             ) | ||||
|             .await | ||||
|             .attach_printable("in 'make_pm_data'")?; | ||||
| @ -3316,6 +3357,9 @@ pub async fn get_additional_payment_data( | ||||
|         api_models::payments::PaymentMethodData::GiftCard(_) => { | ||||
|             api_models::payments::AdditionalPaymentData::GiftCard {} | ||||
|         } | ||||
|         api_models::payments::PaymentMethodData::CardToken(_) => { | ||||
|             api_models::payments::AdditionalPaymentData::CardToken {} | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -3615,6 +3659,12 @@ pub fn get_key_params_for_surcharge_details( | ||||
|             gift_card.get_payment_method_type(), | ||||
|             None, | ||||
|         )), | ||||
|         api_models::payments::PaymentMethodData::CardToken(_) => { | ||||
|             Err(errors::ApiErrorResponse::InvalidDataValue { | ||||
|                 field_name: "payment_method_data", | ||||
|             } | ||||
|             .into()) | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Chethan Rao
					Chethan Rao