diff --git a/crates/router/src/core/payment_methods/cards.rs b/crates/router/src/core/payment_methods/cards.rs index d773ebc8f7..89ef5058b2 100644 --- a/crates/router/src/core/payment_methods/cards.rs +++ b/crates/router/src/core/payment_methods/cards.rs @@ -155,7 +155,7 @@ pub async fn add_card( response } else { let card_id = generate_id(consts::ID_LENGTH, "card"); - mock_add_card(db, &card_id, &card, None, None).await? + mock_add_card(db, &card_id, &card, None, None, Some(&customer_id)).await? }; if let Some(false) = response.duplicate { @@ -188,6 +188,7 @@ pub async fn mock_add_card( card: &api::CardDetail, card_cvc: Option, payment_method_id: Option, + customer_id: Option<&str>, ) -> errors::CustomResult { let locker_mock_up = storage::LockerMockUpNew { card_id: card_id.to_string(), @@ -200,6 +201,7 @@ pub async fn mock_add_card( card_exp_month: card.card_exp_month.peek().to_string(), card_cvc, payment_method_id, + customer_id: customer_id.map(str::to_string), }; let response = db @@ -615,6 +617,7 @@ impl BasiliskCardSupport { &card_detail, None, Some(pm.payment_method_id.to_string()), + Some(&pm.customer_id), ) .await .change_context(errors::ApiErrorResponse::InternalServerError) @@ -758,16 +761,9 @@ pub async fn delete_payment_method( ) -> errors::RouterResponse { let (_, value2) = helpers::Vault::get_payment_method_data_from_locker(state, &pm.payment_method_id).await?; - let payment_method_id = value2.map_or( - Err(errors::ApiErrorResponse::PaymentMethodNotFound), - |pm_value2| { - pm_value2 - .payment_method_id - .map_or(Err(errors::ApiErrorResponse::PaymentMethodNotFound), |x| { - Ok(x) - }) - }, - )?; + let payment_method_id = value2 + .payment_method_id + .map_or(Err(errors::ApiErrorResponse::PaymentMethodNotFound), Ok)?; let pm = state .store .delete_payment_method_by_merchant_id_payment_method_id( diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs index 0cceb93712..1d2d6bfdbe 100644 --- a/crates/router/src/core/payments.rs +++ b/crates/router/src/core/payments.rs @@ -92,24 +92,12 @@ where .await .change_context(errors::ApiErrorResponse::InternalServerError)?; - let (operation, payment_method_data, payment_token) = operation + let (operation, payment_method_data) = operation .to_domain()? - .make_pm_data( - state, - payment_data.payment_attempt.payment_method, - &payment_data.payment_attempt.attempt_id, - &payment_data.payment_attempt, - &payment_data.payment_method_data, - &payment_data.token, - payment_data.card_cvc.clone(), - validate_result.storage_scheme, - ) + .make_pm_data(state, &mut payment_data, validate_result.storage_scheme) .await?; payment_data.payment_method_data = payment_method_data; - if let Some(token) = payment_token { - payment_data.token = Some(token) - } let connector_details = operation .to_domain()? diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index 61a33de4ef..9adbaa6b46 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -19,7 +19,6 @@ use crate::{ }, db::StorageInterface, logger, - pii::Secret, routes::AppState, scheduler::{metrics, workflows::payment_sync}, services, @@ -750,48 +749,71 @@ pub async fn create_customer_if_not_exist<'a, F: Clone, R>( pub async fn make_pm_data<'a, F: Clone, R>( operation: BoxedOperation<'a, F, R>, state: &'a AppState, - payment_method_type: Option, - txn_id: &str, - _payment_attempt: &storage::PaymentAttempt, - request: &Option, - token: &Option, - card_cvc: Option>, -) -> RouterResult<( - BoxedOperation<'a, F, R>, - Option, - Option, -)> { - let (payment_method, payment_token) = match (request, token) { + payment_data: &mut PaymentData, +) -> RouterResult<(BoxedOperation<'a, F, R>, Option)> { + let payment_method_type = payment_data.payment_attempt.payment_method; + let attempt_id = &payment_data.payment_attempt.attempt_id; + let request = &payment_data.payment_method_data; + let token = payment_data.token.clone(); + let card_cvc = payment_data.card_cvc.clone(); + + let payment_method = match (request, token) { (_, Some(token)) => Ok::<_, error_stack::Report>( if payment_method_type == Some(storage_enums::PaymentMethodType::Card) { // TODO: Handle token expiry - let (pm, _) = Vault::get_payment_method_data_from_locker(state, token).await?; - let updated_pm = match (pm.clone(), card_cvc) { + let (pm, tokenize_value2) = + Vault::get_payment_method_data_from_locker(state, &token).await?; + utils::when( + tokenize_value2 + .customer_id + .ne(&payment_data.payment_intent.customer_id), + || { + Err(errors::ApiErrorResponse::PreconditionFailed { message: "customer payment method and customer passed in payment are not same".into() }) + }, + )?; + payment_data.token = Some(token.to_string()); + match (pm.clone(), card_cvc) { (Some(api::PaymentMethod::Card(card)), Some(card_cvc)) => { let mut updated_card = card; updated_card.card_cvc = card_cvc; - Vault::store_payment_method_data_in_locker(state, txn_id, &updated_card) - .await?; + Vault::store_payment_method_data_in_locker( + state, + &token, + &updated_card, + payment_data.payment_intent.customer_id.to_owned(), + ) + .await?; Some(api::PaymentMethod::Card(updated_card)) } (_, _) => pm, - }; - (updated_pm, Some(token.to_string())) + } } else { + utils::when(payment_method_type.is_none(), || { + Err(errors::ApiErrorResponse::MissingRequiredField { + field_name: "payment_method_type".to_owned(), + }) + })?; // TODO: Implement token flow for other payment methods - (None, Some(token.to_string())) + None }, ), (pm @ Some(api::PaymentMethod::Card(card)), _) => { - Vault::store_payment_method_data_in_locker(state, txn_id, card).await?; - Ok((pm.to_owned(), Some(txn_id.to_string()))) + Vault::store_payment_method_data_in_locker( + state, + attempt_id, + card, + payment_data.payment_intent.customer_id.to_owned(), + ) + .await?; + payment_data.token = Some(attempt_id.to_string()); + Ok(pm.to_owned()) } - (pm @ Some(api::PaymentMethod::PayLater(_)), _) => Ok((pm.to_owned(), None)), - (pm @ Some(api::PaymentMethod::Wallet(_)), _) => Ok((pm.to_owned(), None)), - _ => Ok((None, None)), + (pm @ Some(api::PaymentMethod::PayLater(_)), _) => Ok(pm.to_owned()), + (pm @ Some(api::PaymentMethod::Wallet(_)), _) => Ok(pm.to_owned()), + _ => Ok(None), }?; - Ok((operation, payment_method, payment_token)) + Ok((operation, payment_method)) } pub struct Vault {} @@ -802,7 +824,7 @@ impl Vault { pub async fn get_payment_method_data_from_locker( state: &AppState, lookup_key: &str, - ) -> RouterResult<(Option, Option)> { + ) -> RouterResult<(Option, api::TokenizedCardValue2)> { let (resp, card_cvc) = cards::mock_get_card(&*state.store, lookup_key) .await .change_context(errors::ApiErrorResponse::InternalServerError)?; @@ -831,10 +853,10 @@ impl Vault { card_security_code: None, card_fingerprint: None, external_id: None, - customer_id: None, + customer_id: card.customer_id, payment_method_id: Some(card.card_id), }; - Ok((Some(pm), Some(value2))) + Ok((Some(pm), value2)) } #[instrument(skip_all)] @@ -842,6 +864,7 @@ impl Vault { state: &AppState, txn_id: &str, card: &api::CCard, + customer_id: Option, ) -> RouterResult { let card_detail = api::CardDetail { card_number: card.card_number.clone(), @@ -856,6 +879,7 @@ impl Vault { &card_detail, Some(card.card_cvc.peek().clone()), None, + customer_id.as_deref(), ) .await .change_context(errors::ApiErrorResponse::InternalServerError) @@ -887,7 +911,7 @@ impl Vault { pub async fn get_payment_method_data_from_locker( state: &AppState, lookup_key: &str, - ) -> RouterResult<(Option, Option)> { + ) -> RouterResult<(Option, api::TokenizedCardValue2)> { let de_tokenize = cards::get_tokenized_data(state, lookup_key, true).await?; let value1: api::TokenizedCardValue1 = de_tokenize .value1 @@ -907,7 +931,7 @@ impl Vault { card_holder_name: value1.name_on_card.unwrap_or_default().into(), card_cvc: value2.card_security_code.clone().unwrap_or_default().into(), }); - Ok((Some(card), Some(value2))) + Ok((Some(card), value2)) } #[instrument(skip_all)] @@ -915,6 +939,7 @@ impl Vault { state: &AppState, txn_id: &str, card: &api::CCard, + customer_id: Option, ) -> RouterResult { let value1 = transformers::mk_card_value1( card.card_number.peek().clone(), @@ -931,7 +956,7 @@ impl Vault { Some(card.card_cvc.peek().clone()), None, None, - None, + customer_id, None, ) .change_context(errors::ApiErrorResponse::InternalServerError) diff --git a/crates/router/src/core/payments/operations.rs b/crates/router/src/core/payments/operations.rs index 2daa099317..5d127c205a 100644 --- a/crates/router/src/core/payments/operations.rs +++ b/crates/router/src/core/payments/operations.rs @@ -24,7 +24,6 @@ use super::{helpers, CustomerDetails, PaymentData}; use crate::{ core::errors::{self, CustomResult, RouterResult}, db::StorageInterface, - pii::Secret, routes::AppState, types::{ self, @@ -111,18 +110,9 @@ pub trait Domain: Send + Sync { async fn make_pm_data<'a>( &'a self, state: &'a AppState, - _payment_method: Option, - txn_id: &str, - payment_attempt: &storage::PaymentAttempt, - request: &Option, - token: &Option, - card_cvc: Option>, + payment_data: &mut PaymentData, storage_scheme: enums::MerchantStorageScheme, - ) -> RouterResult<( - BoxedOperation<'a, F, R>, - Option, - Option, - )>; + ) -> RouterResult<(BoxedOperation<'a, F, R>, Option)>; async fn add_task_to_process_tracker<'a>( &'a self, @@ -212,29 +202,13 @@ where async fn make_pm_data<'a>( &'a self, state: &'a AppState, - payment_method: Option, - txn_id: &str, - payment_attempt: &storage::PaymentAttempt, - request: &Option, - token: &Option, - card_cvc: Option>, + payment_data: &mut PaymentData, _storage_scheme: enums::MerchantStorageScheme, ) -> RouterResult<( BoxedOperation<'a, F, api::PaymentsRetrieveRequest>, Option, - Option, )> { - helpers::make_pm_data( - Box::new(self), - state, - payment_method, - txn_id, - payment_attempt, - request, - token, - card_cvc, - ) - .await + helpers::make_pm_data(Box::new(self), state, payment_data).await } } @@ -272,19 +246,13 @@ where async fn make_pm_data<'a>( &'a self, _state: &'a AppState, - _payment_method: Option, - _txn_id: &str, - _payment_attempt: &storage::PaymentAttempt, - _request: &Option, - _token: &Option, - _card_cvc: Option>, + _payment_data: &mut PaymentData, _storage_scheme: enums::MerchantStorageScheme, ) -> RouterResult<( BoxedOperation<'a, F, api::PaymentsCaptureRequest>, Option, - Option, )> { - Ok((Box::new(self), None, None)) + Ok((Box::new(self), None)) } async fn get_connector<'a>( @@ -332,19 +300,13 @@ where async fn make_pm_data<'a>( &'a self, _state: &'a AppState, - _payment_method: Option, - _txn_id: &str, - _payment_attempt: &storage::PaymentAttempt, - _request: &Option, - _token: &Option, - _card_cvc: Option>, + _payment_data: &mut PaymentData, _storage_scheme: enums::MerchantStorageScheme, ) -> RouterResult<( BoxedOperation<'a, F, api::PaymentsCancelRequest>, Option, - Option, )> { - Ok((Box::new(self), None, None)) + Ok((Box::new(self), None)) } async fn get_connector<'a>( diff --git a/crates/router/src/core/payments/operations/payment_confirm.rs b/crates/router/src/core/payments/operations/payment_confirm.rs index d1176c97e0..af0c1cc330 100644 --- a/crates/router/src/core/payments/operations/payment_confirm.rs +++ b/crates/router/src/core/payments/operations/payment_confirm.rs @@ -2,7 +2,6 @@ use std::marker::PhantomData; use async_trait::async_trait; use error_stack::{report, ResultExt}; -use masking::Secret; use router_derive::PaymentOperation; use router_env::{instrument, tracing}; @@ -209,37 +208,22 @@ impl Domain for PaymentConfirm { async fn make_pm_data<'a>( &'a self, state: &'a AppState, - payment_method: Option, - txn_id: &str, - payment_attempt: &storage::PaymentAttempt, - request: &Option, - token: &Option, - card_cvc: Option>, + payment_data: &mut PaymentData, _storage_scheme: enums::MerchantStorageScheme, ) -> RouterResult<( BoxedOperation<'a, F, api::PaymentsRequest>, Option, - Option, )> { - let (op, payment_method_data, payment_token) = helpers::make_pm_data( - Box::new(self), - state, - payment_method, - txn_id, - payment_attempt, - request, - token, - card_cvc, - ) - .await?; + let (op, payment_method_data) = + helpers::make_pm_data(Box::new(self), state, payment_data).await?; - if payment_method != Some(enums::PaymentMethodType::Paypal) { + if payment_data.payment_attempt.payment_method != Some(enums::PaymentMethodType::Paypal) { utils::when(payment_method_data.is_none(), || { Err(errors::ApiErrorResponse::PaymentMethodNotFound) })?; } - Ok((op, payment_method_data, payment_token)) + Ok((op, payment_method_data)) } #[instrument(skip_all)] diff --git a/crates/router/src/core/payments/operations/payment_create.rs b/crates/router/src/core/payments/operations/payment_create.rs index ceb4f5df03..eb1cf1d533 100644 --- a/crates/router/src/core/payments/operations/payment_create.rs +++ b/crates/router/src/core/payments/operations/payment_create.rs @@ -3,7 +3,6 @@ use std::marker::PhantomData; use async_trait::async_trait; use common_utils::ext_traits::AsyncExt; use error_stack::ResultExt; -use masking::Secret; use router_derive::PaymentOperation; use router_env::{instrument, tracing}; use uuid::Uuid; @@ -271,29 +270,13 @@ impl Domain for PaymentCreate { async fn make_pm_data<'a>( &'a self, state: &'a AppState, - payment_method: Option, - txn_id: &str, - payment_attempt: &storage::PaymentAttempt, - request: &Option, - token: &Option, - card_cvc: Option>, + payment_data: &mut PaymentData, _storage_scheme: enums::MerchantStorageScheme, ) -> RouterResult<( BoxedOperation<'a, F, api::PaymentsRequest>, Option, - Option, )> { - helpers::make_pm_data( - Box::new(self), - state, - payment_method, - txn_id, - payment_attempt, - request, - token, - card_cvc, - ) - .await + helpers::make_pm_data(Box::new(self), state, payment_data).await } #[instrument(skip_all)] diff --git a/crates/router/src/core/payments/operations/payment_method_validate.rs b/crates/router/src/core/payments/operations/payment_method_validate.rs index 5e9b510ca3..c57b499ff2 100644 --- a/crates/router/src/core/payments/operations/payment_method_validate.rs +++ b/crates/router/src/core/payments/operations/payment_method_validate.rs @@ -16,7 +16,6 @@ use crate::{ utils as core_utils, }, db::StorageInterface, - pii::Secret, routes::AppState, types::{ self, @@ -237,29 +236,13 @@ where async fn make_pm_data<'a>( &'a self, state: &'a AppState, - payment_method: Option, - txn_id: &str, - payment_attempt: &storage::PaymentAttempt, - request: &Option, - token: &Option, - card_cvc: Option>, + payment_data: &mut PaymentData, _storage_scheme: storage_enums::MerchantStorageScheme, ) -> RouterResult<( BoxedOperation<'a, F, api::VerifyRequest>, Option, - Option, )> { - helpers::make_pm_data( - Box::new(self), - state, - payment_method, - txn_id, - payment_attempt, - request, - token, - card_cvc, - ) - .await + helpers::make_pm_data(Box::new(self), state, payment_data).await } async fn get_connector<'a>( diff --git a/crates/router/src/core/payments/operations/payment_session.rs b/crates/router/src/core/payments/operations/payment_session.rs index 9f940cf396..d104eead10 100644 --- a/crates/router/src/core/payments/operations/payment_session.rs +++ b/crates/router/src/core/payments/operations/payment_session.rs @@ -253,20 +253,14 @@ where async fn make_pm_data<'b>( &'b self, _state: &'b AppState, - _payment_method: Option, - _txn_id: &str, - _payment_attempt: &storage::PaymentAttempt, - _request: &Option, - _token: &Option, - _card_cvc: Option>, + _payment_data: &mut PaymentData, _storage_scheme: enums::MerchantStorageScheme, ) -> RouterResult<( BoxedOperation<'b, F, api::PaymentsSessionRequest>, Option, - Option, )> { //No payment method data for this operation - Ok((Box::new(self), None, None)) + Ok((Box::new(self), None)) } async fn get_connector<'a>( diff --git a/crates/router/src/core/payments/operations/payment_start.rs b/crates/router/src/core/payments/operations/payment_start.rs index 8f086e6695..6ffb441de2 100644 --- a/crates/router/src/core/payments/operations/payment_start.rs +++ b/crates/router/src/core/payments/operations/payment_start.rs @@ -238,29 +238,13 @@ where async fn make_pm_data<'a>( &'a self, state: &'a AppState, - payment_method: Option, - txn_id: &str, - payment_attempt: &storage::PaymentAttempt, - request: &Option, - token: &Option, - card_cvc: Option>, + payment_data: &mut PaymentData, _storage_scheme: enums::MerchantStorageScheme, ) -> RouterResult<( BoxedOperation<'a, F, api::PaymentsStartRequest>, Option, - Option, )> { - helpers::make_pm_data( - Box::new(self), - state, - payment_method, - txn_id, - payment_attempt, - request, - token, - card_cvc, - ) - .await + helpers::make_pm_data(Box::new(self), state, payment_data).await } async fn get_connector<'a>( diff --git a/crates/router/src/core/payments/operations/payment_status.rs b/crates/router/src/core/payments/operations/payment_status.rs index 105f28506d..7736ffdf87 100644 --- a/crates/router/src/core/payments/operations/payment_status.rs +++ b/crates/router/src/core/payments/operations/payment_status.rs @@ -2,7 +2,6 @@ use std::marker::PhantomData; use async_trait::async_trait; use error_stack::ResultExt; -use masking::Secret; use router_derive::PaymentOperation; use router_env::{instrument, tracing}; @@ -79,29 +78,13 @@ impl Domain for PaymentStatus { async fn make_pm_data<'a>( &'a self, state: &'a AppState, - payment_method: Option, - txn_id: &str, - payment_attempt: &storage::PaymentAttempt, - request: &Option, - token: &Option, - card_cvc: Option>, + payment_data: &mut PaymentData, _storage_scheme: enums::MerchantStorageScheme, ) -> RouterResult<( BoxedOperation<'a, F, api::PaymentsRequest>, Option, - Option, )> { - helpers::make_pm_data( - Box::new(self), - state, - payment_method, - txn_id, - payment_attempt, - request, - token, - card_cvc, - ) - .await + helpers::make_pm_data(Box::new(self), state, payment_data).await } #[instrument(skip_all)] diff --git a/crates/router/src/core/payments/operations/payment_update.rs b/crates/router/src/core/payments/operations/payment_update.rs index 810dec8f32..427e9fbc3d 100644 --- a/crates/router/src/core/payments/operations/payment_update.rs +++ b/crates/router/src/core/payments/operations/payment_update.rs @@ -3,7 +3,6 @@ use std::marker::PhantomData; use async_trait::async_trait; use common_utils::ext_traits::AsyncExt; use error_stack::{report, ResultExt}; -use masking::Secret; use router_derive::PaymentOperation; use router_env::{instrument, tracing}; @@ -232,29 +231,13 @@ impl Domain for PaymentUpdate { async fn make_pm_data<'a>( &'a self, state: &'a AppState, - payment_method: Option, - txn_id: &str, - payment_attempt: &storage::PaymentAttempt, - request: &Option, - token: &Option, - card_cvc: Option>, + payment_data: &mut PaymentData, _storage_scheme: enums::MerchantStorageScheme, ) -> RouterResult<( BoxedOperation<'a, F, api::PaymentsRequest>, Option, - Option, )> { - helpers::make_pm_data( - Box::new(self), - state, - payment_method, - txn_id, - payment_attempt, - request, - token, - card_cvc, - ) - .await + helpers::make_pm_data(Box::new(self), state, payment_data).await } #[instrument(skip_all)] diff --git a/crates/storage_models/src/locker_mock_up.rs b/crates/storage_models/src/locker_mock_up.rs index 8190244c31..19553f1cb9 100644 --- a/crates/storage_models/src/locker_mock_up.rs +++ b/crates/storage_models/src/locker_mock_up.rs @@ -35,4 +35,5 @@ pub struct LockerMockUpNew { pub card_exp_month: String, pub card_cvc: Option, pub payment_method_id: Option, + pub customer_id: Option, }