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:
Chethan Rao
2023-11-28 16:22:33 +05:30
committed by GitHub
parent c0116db271
commit e7ad3a4db8
40 changed files with 375 additions and 237 deletions

View File

@ -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())
}
}
}