mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 17:19:15 +08:00
fix(router): allow inferring payment method from payment token (#422)
This commit is contained in:
@ -673,17 +673,21 @@ pub async fn make_pm_data<'a, F: Clone, R>(
|
|||||||
state: &'a AppState,
|
state: &'a AppState,
|
||||||
payment_data: &mut PaymentData<F>,
|
payment_data: &mut PaymentData<F>,
|
||||||
) -> RouterResult<(BoxedOperation<'a, F, R>, Option<api::PaymentMethod>)> {
|
) -> RouterResult<(BoxedOperation<'a, F, R>, Option<api::PaymentMethod>)> {
|
||||||
let payment_method_type = payment_data.payment_attempt.payment_method;
|
|
||||||
let request = &payment_data.payment_method_data;
|
let request = &payment_data.payment_method_data;
|
||||||
let token = payment_data.token.clone();
|
let token = payment_data.token.clone();
|
||||||
let card_cvc = payment_data.card_cvc.clone();
|
let card_cvc = payment_data.card_cvc.clone();
|
||||||
|
|
||||||
|
// TODO: Handle case where payment method and token both are present in request properly.
|
||||||
let payment_method = match (request, token) {
|
let payment_method = match (request, token) {
|
||||||
(_, Some(token)) => Ok::<_, error_stack::Report<errors::ApiErrorResponse>>(
|
(_, Some(token)) => {
|
||||||
if payment_method_type == Some(storage_enums::PaymentMethodType::Card) {
|
let (pm, supplementary_data) = vault::Vault::get_payment_method_data_from_locker(
|
||||||
// TODO: Handle token expiry
|
state, &token,
|
||||||
let (pm, supplementary_data) =
|
)
|
||||||
vault::Vault::get_payment_method_data_from_locker(state, &token).await?;
|
.await
|
||||||
|
.attach_printable(
|
||||||
|
"Payment method for given token not found or there was a problem fetching it",
|
||||||
|
)?;
|
||||||
|
|
||||||
utils::when(
|
utils::when(
|
||||||
supplementary_data
|
supplementary_data
|
||||||
.customer_id
|
.customer_id
|
||||||
@ -692,11 +696,14 @@ pub async fn make_pm_data<'a, F: Clone, R>(
|
|||||||
Err(errors::ApiErrorResponse::PreconditionFailed { message: "customer associated with payment method and customer passed in payment are not same".into() })
|
Err(errors::ApiErrorResponse::PreconditionFailed { message: "customer associated with payment method and customer passed in payment are not same".into() })
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
payment_data.token = Some(token.to_string());
|
|
||||||
match (pm.clone(), card_cvc) {
|
Ok::<_, error_stack::Report<errors::ApiErrorResponse>>(match pm.clone() {
|
||||||
(Some(api::PaymentMethod::Card(card)), Some(card_cvc)) => {
|
Some(api::PaymentMethod::Card(card)) => {
|
||||||
|
payment_data.payment_attempt.payment_method =
|
||||||
|
Some(storage_enums::PaymentMethodType::Card);
|
||||||
|
if let Some(cvc) = card_cvc {
|
||||||
let mut updated_card = card;
|
let mut updated_card = card;
|
||||||
updated_card.card_cvc = card_cvc;
|
updated_card.card_cvc = cvc;
|
||||||
let updated_pm = api::PaymentMethod::Card(updated_card);
|
let updated_pm = api::PaymentMethod::Card(updated_card);
|
||||||
vault::Vault::store_payment_method_data_in_locker(
|
vault::Vault::store_payment_method_data_in_locker(
|
||||||
state,
|
state,
|
||||||
@ -706,24 +713,15 @@ pub async fn make_pm_data<'a, F: Clone, R>(
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Some(updated_pm)
|
Some(updated_pm)
|
||||||
|
} else {
|
||||||
|
pm
|
||||||
}
|
}
|
||||||
(_, _) => pm,
|
|
||||||
}
|
}
|
||||||
} else if payment_method_type == Some(storage_enums::PaymentMethodType::Wallet) {
|
|
||||||
let (pm, supplementary_data) =
|
|
||||||
vault::Vault::get_payment_method_data_from_locker(state, &token).await?;
|
|
||||||
|
|
||||||
utils::when(
|
|
||||||
supplementary_data
|
|
||||||
.customer_id
|
|
||||||
.ne(&payment_data.payment_intent.customer_id),
|
|
||||||
|| {
|
|
||||||
Err(errors::ApiErrorResponse::PreconditionFailed { message: "customer associated with payment method and customer passed in payment are not same".into() })
|
|
||||||
},
|
|
||||||
)?;
|
|
||||||
payment_data.token = Some(token.to_string());
|
|
||||||
match pm.clone() {
|
|
||||||
Some(api::PaymentMethod::Wallet(wallet_data)) => {
|
Some(api::PaymentMethod::Wallet(wallet_data)) => {
|
||||||
|
payment_data.payment_attempt.payment_method =
|
||||||
|
Some(storage_enums::PaymentMethodType::Wallet);
|
||||||
|
// TODO: Remove redundant update from wallets.
|
||||||
if wallet_data.token.is_some() {
|
if wallet_data.token.is_some() {
|
||||||
let updated_pm = api::PaymentMethod::Wallet(wallet_data);
|
let updated_pm = api::PaymentMethod::Wallet(wallet_data);
|
||||||
vault::Vault::store_payment_method_data_in_locker(
|
vault::Vault::store_payment_method_data_in_locker(
|
||||||
@ -738,18 +736,16 @@ pub async fn make_pm_data<'a, F: Clone, R>(
|
|||||||
pm
|
pm
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => pm,
|
|
||||||
}
|
Some(_) => Err(errors::ApiErrorResponse::InternalServerError)
|
||||||
} else {
|
.into_report()
|
||||||
utils::when(payment_method_type.is_none(), || {
|
.attach_printable(
|
||||||
Err(errors::ApiErrorResponse::MissingRequiredField {
|
"Payment method received from locker is unsupported by locker",
|
||||||
field_name: "payment_method_type".to_owned(),
|
)?,
|
||||||
|
|
||||||
|
None => None,
|
||||||
})
|
})
|
||||||
})?;
|
}
|
||||||
// [#195]: Implement token flow for other payment methods
|
|
||||||
None
|
|
||||||
},
|
|
||||||
),
|
|
||||||
(pm_opt @ Some(pm @ api::PaymentMethod::Card(_)), _) => {
|
(pm_opt @ Some(pm @ api::PaymentMethod::Card(_)), _) => {
|
||||||
let token = vault::Vault::store_payment_method_data_in_locker(
|
let token = vault::Vault::store_payment_method_data_in_locker(
|
||||||
state,
|
state,
|
||||||
@ -840,7 +836,9 @@ pub(crate) fn validate_payment_method_fields_present(
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
utils::when(
|
utils::when(
|
||||||
req.payment_method.is_some() && req.payment_method_data.is_none(),
|
req.payment_method.is_some()
|
||||||
|
&& req.payment_method_data.is_none()
|
||||||
|
&& req.payment_token.is_none(),
|
||||||
|| {
|
|| {
|
||||||
Err(errors::ApiErrorResponse::MissingRequiredField {
|
Err(errors::ApiErrorResponse::MissingRequiredField {
|
||||||
field_name: "payment_method_data".to_string(),
|
field_name: "payment_method_data".to_string(),
|
||||||
|
|||||||
Reference in New Issue
Block a user