From 1753a02896c4a7d64e2bf92a8f2325eac0a1045c Mon Sep 17 00:00:00 2001 From: Sanchith Hegde <22217505+SanchithHegde@users.noreply.github.com> Date: Sun, 1 Dec 2024 19:42:02 +0530 Subject: [PATCH] feat(payment_methods_v2): implement a barebones version of list customer payment methods v2 (#6649) --- api-reference-v2/openapi_spec.json | 8 +- api-reference/openapi_spec.json | 4 +- crates/api_models/src/payment_methods.rs | 14 +- crates/common_utils/src/id_type/global_id.rs | 4 +- .../src/id_type/global_id/payment.rs | 4 +- .../src/id_type/global_id/payment_methods.rs | 5 +- .../src/id_type/global_id/refunds.rs | 2 +- .../src/payment_methods.rs | 7 +- crates/router/src/core/payment_methods.rs | 179 ++++++++++-------- .../router/src/core/payment_methods/cards.rs | 30 +-- crates/router/src/core/payments.rs | 2 +- crates/router/src/lib.rs | 9 +- crates/router/src/routes/app.rs | 8 +- crates/router/src/services/authentication.rs | 48 ----- .../src/types/storage/payment_method.rs | 36 ++++ 15 files changed, 173 insertions(+), 187 deletions(-) diff --git a/api-reference-v2/openapi_spec.json b/api-reference-v2/openapi_spec.json index 2b66d1755ff8..e3f54813a43d 100644 --- a/api-reference-v2/openapi_spec.json +++ b/api-reference-v2/openapi_spec.json @@ -7153,6 +7153,7 @@ "customer_id", "payment_method_type", "recurring_enabled", + "created", "requires_cvv", "is_default" ], @@ -7210,9 +7211,8 @@ "created": { "type": "string", "format": "date-time", - "description": "A timestamp (ISO 8601 code) that determines when the customer was created", - "example": "2023-01-18T11:04:09.922Z", - "nullable": true + "description": "A timestamp (ISO 8601 code) that determines when the payment method was created", + "example": "2023-01-18T11:04:09.922Z" }, "surcharge_details": { "allOf": [ @@ -13542,7 +13542,7 @@ "created": { "type": "string", "format": "date-time", - "description": "A timestamp (ISO 8601 code) that determines when the customer was created", + "description": "A timestamp (ISO 8601 code) that determines when the payment method was created", "example": "2023-01-18T11:04:09.922Z", "nullable": true }, diff --git a/api-reference/openapi_spec.json b/api-reference/openapi_spec.json index d2133a3e68e4..25ed2648cd4a 100644 --- a/api-reference/openapi_spec.json +++ b/api-reference/openapi_spec.json @@ -9739,7 +9739,7 @@ "created": { "type": "string", "format": "date-time", - "description": "A timestamp (ISO 8601 code) that determines when the customer was created", + "description": "A timestamp (ISO 8601 code) that determines when the payment method was created", "example": "2023-01-18T11:04:09.922Z", "nullable": true }, @@ -16326,7 +16326,7 @@ "created": { "type": "string", "format": "date-time", - "description": "A timestamp (ISO 8601 code) that determines when the customer was created", + "description": "A timestamp (ISO 8601 code) that determines when the payment method was created", "example": "2023-01-18T11:04:09.922Z", "nullable": true }, diff --git a/crates/api_models/src/payment_methods.rs b/crates/api_models/src/payment_methods.rs index 2c2aa4861c55..283a0d662d71 100644 --- a/crates/api_models/src/payment_methods.rs +++ b/crates/api_models/src/payment_methods.rs @@ -755,7 +755,7 @@ pub struct PaymentMethodResponse { #[schema(value_type = Option, example = json!({ "city": "NY", "unit": "245" }))] pub metadata: Option, - /// A timestamp (ISO 8601 code) that determines when the customer was created + /// A timestamp (ISO 8601 code) that determines when the payment method was created #[schema(value_type = Option, example = "2023-01-18T11:04:09.922Z")] #[serde(default, with = "common_utils::custom_serde::iso8601::option")] pub created: Option, @@ -801,7 +801,7 @@ pub struct PaymentMethodResponse { #[schema(example = true)] pub recurring_enabled: bool, - /// A timestamp (ISO 8601 code) that determines when the customer was created + /// A timestamp (ISO 8601 code) that determines when the payment method was created #[schema(value_type = Option, example = "2023-01-18T11:04:09.922Z")] #[serde(default, with = "common_utils::custom_serde::iso8601::option")] pub created: Option, @@ -1802,10 +1802,10 @@ pub struct CustomerPaymentMethod { #[schema(example = json!({"mask": "0000"}))] pub bank: Option, - /// A timestamp (ISO 8601 code) that determines when the customer was created - #[schema(value_type = Option,example = "2023-01-18T11:04:09.922Z")] - #[serde(default, with = "common_utils::custom_serde::iso8601::option")] - pub created: Option, + /// A timestamp (ISO 8601 code) that determines when the payment method was created + #[schema(value_type = PrimitiveDateTime, example = "2023-01-18T11:04:09.922Z")] + #[serde(with = "common_utils::custom_serde::iso8601")] + pub created: time::PrimitiveDateTime, /// Surcharge details for this saved card pub surcharge_details: Option, @@ -1890,7 +1890,7 @@ pub struct CustomerPaymentMethod { #[schema(value_type = Option,example = json!({ "city": "NY", "unit": "245" }))] pub metadata: Option, - /// A timestamp (ISO 8601 code) that determines when the customer was created + /// A timestamp (ISO 8601 code) that determines when the payment method was created #[schema(value_type = Option,example = "2023-01-18T11:04:09.922Z")] #[serde(default, with = "common_utils::custom_serde::iso8601::option")] pub created: Option, diff --git a/crates/common_utils/src/id_type/global_id.rs b/crates/common_utils/src/id_type/global_id.rs index 5490dcda7bd4..a54df7585870 100644 --- a/crates/common_utils/src/id_type/global_id.rs +++ b/crates/common_utils/src/id_type/global_id.rs @@ -120,7 +120,7 @@ pub(crate) enum GlobalIdError { impl GlobalId { /// Create a new global id from entity and cell information /// The entity prefix is used to identify the entity, `cus` for customers, `pay`` for payments etc. - pub fn generate(cell_id: CellId, entity: GlobalEntity) -> Self { + pub fn generate(cell_id: &CellId, entity: GlobalEntity) -> Self { let prefix = format!("{}_{}", cell_id.get_string_repr(), entity.prefix()); let id = generate_time_ordered_id(&prefix); let alphanumeric_id = AlphaNumericId::new_unchecked(id); @@ -201,7 +201,7 @@ mod global_id_tests { let cell_id_string = "12345"; let entity = GlobalEntity::Customer; let cell_id = CellId::from_str(cell_id_string).unwrap(); - let global_id = GlobalId::generate(cell_id, entity); + let global_id = GlobalId::generate(&cell_id, entity); /// Generate a regex for globalid /// Eg - 12abc_cus_abcdefghijklmnopqrstuvwxyz1234567890 diff --git a/crates/common_utils/src/id_type/global_id/payment.rs b/crates/common_utils/src/id_type/global_id/payment.rs index 934d710604c5..5a2da3998bb6 100644 --- a/crates/common_utils/src/id_type/global_id/payment.rs +++ b/crates/common_utils/src/id_type/global_id/payment.rs @@ -20,7 +20,7 @@ impl GlobalPaymentId { } /// Generate a new GlobalPaymentId from a cell id - pub fn generate(cell_id: crate::id_type::CellId) -> Self { + pub fn generate(cell_id: &crate::id_type::CellId) -> Self { let global_id = super::GlobalId::generate(cell_id, super::GlobalEntity::Payment); Self(global_id) } @@ -57,7 +57,7 @@ crate::impl_to_sql_from_sql_global_id_type!(GlobalAttemptId); impl GlobalAttemptId { /// Generate a new GlobalAttemptId from a cell id pub fn generate(cell_id: &super::CellId) -> Self { - let global_id = super::GlobalId::generate(cell_id.clone(), super::GlobalEntity::Attempt); + let global_id = super::GlobalId::generate(cell_id, super::GlobalEntity::Attempt); Self(global_id) } diff --git a/crates/common_utils/src/id_type/global_id/payment_methods.rs b/crates/common_utils/src/id_type/global_id/payment_methods.rs index f6f394242cca..40bd6ec0df4a 100644 --- a/crates/common_utils/src/id_type/global_id/payment_methods.rs +++ b/crates/common_utils/src/id_type/global_id/payment_methods.rs @@ -28,10 +28,7 @@ pub enum GlobalPaymentMethodIdError { impl GlobalPaymentMethodId { /// Create a new GlobalPaymentMethodId from cell id information - pub fn generate(cell_id: &str) -> error_stack::Result { - let cell_id = CellId::from_str(cell_id) - .change_context(GlobalPaymentMethodIdError::ConstructionError) - .attach_printable("Failed to construct CellId from str")?; + pub fn generate(cell_id: &CellId) -> error_stack::Result { let global_id = GlobalId::generate(cell_id, GlobalEntity::PaymentMethod); Ok(Self(global_id)) } diff --git a/crates/common_utils/src/id_type/global_id/refunds.rs b/crates/common_utils/src/id_type/global_id/refunds.rs index 64e475161140..0aac9bf5808e 100644 --- a/crates/common_utils/src/id_type/global_id/refunds.rs +++ b/crates/common_utils/src/id_type/global_id/refunds.rs @@ -26,7 +26,7 @@ impl GlobalRefundId { } /// Generate a new GlobalRefundId from a cell id - pub fn generate(cell_id: crate::id_type::CellId) -> Self { + pub fn generate(cell_id: &crate::id_type::CellId) -> Self { let global_id = super::GlobalId::generate(cell_id, super::GlobalEntity::Refund); Self(global_id) } diff --git a/crates/hyperswitch_domain_models/src/payment_methods.rs b/crates/hyperswitch_domain_models/src/payment_methods.rs index 083d6e475019..4e7d727839b2 100644 --- a/crates/hyperswitch_domain_models/src/payment_methods.rs +++ b/crates/hyperswitch_domain_models/src/payment_methods.rs @@ -12,7 +12,7 @@ use masking::{PeekInterface, Secret}; use time::PrimitiveDateTime; #[cfg(all(feature = "v2", feature = "payment_methods_v2"))] -use crate::type_encryption::EncryptedJsonType; +use crate::type_encryption::OptionalEncryptableJsonType; use crate::type_encryption::{crypto_operation, AsyncLift, CryptoOperation}; #[cfg(all(feature = "v2", feature = "payment_methods_v2"))] @@ -80,9 +80,8 @@ pub struct PaymentMethod { pub last_modified: PrimitiveDateTime, pub payment_method_type: Option, pub payment_method_subtype: Option, - pub payment_method_data: Option< - Encryptable>>, - >, + pub payment_method_data: + OptionalEncryptableJsonType, pub locker_id: Option, pub last_used_at: PrimitiveDateTime, pub connector_mandate_details: Option, diff --git a/crates/router/src/core/payment_methods.rs b/crates/router/src/core/payment_methods.rs index 8b8b3f33ed80..599d696ec06d 100644 --- a/crates/router/src/core/payment_methods.rs +++ b/crates/router/src/core/payment_methods.rs @@ -865,9 +865,10 @@ pub async fn create_payment_method( .attach_printable("Unable to encrypt Payment method billing address")?; // create pm - let payment_method_id = id_type::GlobalPaymentMethodId::generate("random_cell_id") - .change_context(errors::ApiErrorResponse::InternalServerError) - .attach_printable("Unable to generate GlobalPaymentMethodId")?; + let payment_method_id = + id_type::GlobalPaymentMethodId::generate(&state.conf.cell_information.id) + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Unable to generate GlobalPaymentMethodId")?; let payment_method = create_payment_method_for_intent( state, @@ -978,9 +979,10 @@ pub async fn payment_method_intent_create( // create pm entry - let payment_method_id = id_type::GlobalPaymentMethodId::generate("random_cell_id") - .change_context(errors::ApiErrorResponse::InternalServerError) - .attach_printable("Unable to generate GlobalPaymentMethodId")?; + let payment_method_id = + id_type::GlobalPaymentMethodId::generate(&state.conf.cell_information.id) + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Unable to generate GlobalPaymentMethodId")?; let payment_method = create_payment_method_for_intent( state, @@ -1324,69 +1326,82 @@ pub async fn vault_payment_method( feature = "customer_v2" ))] async fn get_pm_list_context( - state: &SessionState, - payment_method: &enums::PaymentMethod, - _key_store: &domain::MerchantKeyStore, - pm: &domain::PaymentMethod, - _parent_payment_method_token: Option, + payment_method_type: enums::PaymentMethod, + payment_method: &domain::PaymentMethod, is_payment_associated: bool, ) -> Result, error_stack::Report> { - let payment_method_retrieval_context = match payment_method { - enums::PaymentMethod::Card => { - let card_details = cards::get_card_details_with_locker_fallback(pm, state).await?; - - card_details.as_ref().map(|card| PaymentMethodListContext { - card_details: Some(card.clone()), - #[cfg(feature = "payouts")] - bank_transfer_details: None, - hyperswitch_token_data: is_payment_associated.then_some( + let payment_method_data = payment_method + .payment_method_data + .clone() + .map(|payment_method_data| payment_method_data.into_inner().expose().into_inner()); + + let payment_method_retrieval_context = match payment_method_data { + Some(payment_methods::PaymentMethodsData::Card(card)) => { + Some(PaymentMethodListContext::Card { + card_details: api::CardDetailFromLocker::from(card), + token_data: is_payment_associated.then_some( storage::PaymentTokenData::permanent_card( - Some(pm.get_id().clone()), - pm.locker_id + Some(payment_method.get_id().clone()), + payment_method + .locker_id .as_ref() - .map(|id| id.get_string_repr().clone()) - .or(Some(pm.get_id().get_string_repr().to_owned())), - pm.locker_id + .map(|id| id.get_string_repr().to_owned()) + .or_else(|| Some(payment_method.get_id().get_string_repr().to_owned())), + payment_method + .locker_id .as_ref() - .map(|id| id.get_string_repr().clone()) - .unwrap_or(pm.get_id().get_string_repr().to_owned()), + .map(|id| id.get_string_repr().to_owned()) + .unwrap_or_else(|| { + payment_method.get_id().get_string_repr().to_owned() + }), ), ), }) } + Some(payment_methods::PaymentMethodsData::BankDetails(bank_details)) => { + let get_bank_account_token_data = + || -> errors::CustomResult { + let connector_details = bank_details + .connector_details + .first() + .cloned() + .ok_or(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Failed to obtain bank account connector details")?; + + let payment_method_subtype = payment_method + .get_payment_method_subtype() + .get_required_value("payment_method_subtype") + .attach_printable("PaymentMethodType not found")?; + + Ok(payment_methods::BankAccountTokenData { + payment_method_type: payment_method_subtype, + payment_method: payment_method_type, + connector_details, + }) + }; - enums::PaymentMethod::BankDebit => { // Retrieve the pm_auth connector details so that it can be tokenized - let bank_account_token_data = cards::get_bank_account_connector_details(pm) - .await - .unwrap_or_else(|err| { - logger::error!(error=?err); - None - }); - + let bank_account_token_data = get_bank_account_token_data() + .inspect_err(|error| logger::error!(?error)) + .ok(); bank_account_token_data.map(|data| { let token_data = storage::PaymentTokenData::AuthBankDebit(data); - PaymentMethodListContext { - card_details: None, - #[cfg(feature = "payouts")] - bank_transfer_details: None, - hyperswitch_token_data: is_payment_associated.then_some(token_data), + PaymentMethodListContext::Bank { + token_data: is_payment_associated.then_some(token_data), } }) } - - _ => Some(PaymentMethodListContext { - card_details: None, - #[cfg(feature = "payouts")] - bank_transfer_details: None, - hyperswitch_token_data: is_payment_associated.then_some( - storage::PaymentTokenData::temporary_generic(generate_id( - consts::ID_LENGTH, - "token", - )), - ), - }), + Some(payment_methods::PaymentMethodsData::WalletDetails(_)) | None => { + Some(PaymentMethodListContext::TemporaryToken { + token_data: is_payment_associated.then_some( + storage::PaymentTokenData::temporary_generic(generate_id( + consts::ID_LENGTH, + "token", + )), + ), + }) + } }; Ok(payment_method_retrieval_context) @@ -1471,9 +1486,9 @@ pub async fn list_customer_payment_method( let key_manager_state = &(state).into(); let customer = db - .find_customer_by_merchant_reference_id_merchant_id( + .find_customer_by_global_id( key_manager_state, - customer_id, + customer_id.get_string_repr(), merchant_account.get_id(), &key_store, merchant_account.storage_scheme, @@ -1509,25 +1524,23 @@ pub async fn list_customer_payment_method( .to_not_found_response(errors::ApiErrorResponse::PaymentMethodNotFound)?; let mut filtered_saved_payment_methods_ctx = Vec::new(); - for pm in saved_payment_methods.into_iter() { - let payment_method = pm + for payment_method in saved_payment_methods.into_iter() { + let payment_method_type = payment_method .get_payment_method_type() .get_required_value("payment_method")?; let parent_payment_method_token = is_payment_associated.then(|| generate_id(consts::ID_LENGTH, "token")); - let pm_list_context = get_pm_list_context( - state, - &payment_method, - &key_store, - &pm, - parent_payment_method_token.clone(), - is_payment_associated, - ) - .await?; + let pm_list_context = + get_pm_list_context(payment_method_type, &payment_method, is_payment_associated) + .await?; if let Some(ctx) = pm_list_context { - filtered_saved_payment_methods_ctx.push((ctx, parent_payment_method_token, pm)); + filtered_saved_payment_methods_ctx.push(( + ctx, + parent_payment_method_token, + payment_method, + )); } } @@ -1576,6 +1589,8 @@ pub async fn list_customer_payment_method( is_guest_customer: is_payment_associated.then_some(false), //to return this key only when the request is tied to a payment intent }; + /* + TODO: Implement surcharge for v2 if is_payment_associated { Box::pin(cards::perform_surcharge_ops( payments_info.as_ref().map(|pi| pi.payment_intent.clone()), @@ -1587,6 +1602,7 @@ pub async fn list_customer_payment_method( )) .await?; } + */ Ok(services::ApplicationResponse::Json(response)) } @@ -1661,15 +1677,20 @@ async fn generate_saved_pm_response( requires_cvv && !(off_session_payment_flag && pm.connector_mandate_details.is_some()) }; - let pmd = if let Some(card) = pm_list_context.card_details.as_ref() { - Some(api::PaymentMethodListData::Card(card.clone())) - } else if cfg!(feature = "payouts") { - pm_list_context - .bank_transfer_details - .clone() - .map(api::PaymentMethodListData::Bank) - } else { - None + let pmd = match &pm_list_context { + PaymentMethodListContext::Card { card_details, .. } => { + Some(api::PaymentMethodListData::Card(card_details.clone())) + } + #[cfg(feature = "payouts")] + PaymentMethodListContext::BankTransfer { + bank_transfer_details, + .. + } => Some(api::PaymentMethodListData::Bank( + bank_transfer_details.clone(), + )), + PaymentMethodListContext::Bank { .. } | PaymentMethodListContext::TemporaryToken { .. } => { + None + } }; let pma = api::CustomerPaymentMethod { @@ -1680,7 +1701,7 @@ async fn generate_saved_pm_response( payment_method_subtype: pm.get_payment_method_subtype(), payment_method_data: pmd, recurring_enabled: mca_enabled, - created: Some(pm.created_at), + created: pm.created_at, bank: bank_details, surcharge_details: None, requires_cvv: requires_cvv @@ -1952,8 +1973,8 @@ impl pm_types::SavedPMLPaymentsInfo { let token = parent_payment_method_token .as_ref() .get_required_value("parent_payment_method_token")?; - let hyperswitch_token_data = pm_list_context - .hyperswitch_token_data + let token_data = pm_list_context + .get_token_data() .get_required_value("PaymentTokenData")?; let intent_fulfillment_time = self @@ -1962,7 +1983,7 @@ impl pm_types::SavedPMLPaymentsInfo { .unwrap_or(common_utils::consts::DEFAULT_INTENT_FULFILLMENT_TIME); pm_routes::ParentPaymentMethodToken::create_key_for_token((token, pma.payment_method_type)) - .insert(intent_fulfillment_time, hyperswitch_token_data, state) + .insert(intent_fulfillment_time, token_data, state) .await?; Ok(()) diff --git a/crates/router/src/core/payment_methods/cards.rs b/crates/router/src/core/payment_methods/cards.rs index 955cc37b0d9c..9cfe6e6ec738 100644 --- a/crates/router/src/core/payment_methods/cards.rs +++ b/crates/router/src/core/payment_methods/cards.rs @@ -5328,14 +5328,6 @@ pub async fn get_card_details_with_locker_fallback( }) } -#[cfg(all(feature = "v2", feature = "payment_methods_v2"))] -pub async fn get_card_details_with_locker_fallback( - pm: &domain::PaymentMethod, - state: &routes::SessionState, -) -> errors::RouterResult> { - todo!() -} - #[cfg(all( any(feature = "v2", feature = "v1"), not(feature = "payment_methods_v2") @@ -5365,14 +5357,6 @@ pub async fn get_card_details_without_locker_fallback( }) } -#[cfg(all(feature = "v2", feature = "payment_methods_v2"))] -pub async fn get_card_details_without_locker_fallback( - pm: &domain::PaymentMethod, - state: &routes::SessionState, -) -> errors::RouterResult { - todo!() -} - #[cfg(all( any(feature = "v2", feature = "v1"), not(feature = "payment_methods_v2") @@ -5460,13 +5444,13 @@ pub async fn get_masked_bank_details( } } +#[cfg(all( + any(feature = "v2", feature = "v1"), + not(feature = "payment_methods_v2") +))] pub async fn get_bank_account_connector_details( pm: &domain::PaymentMethod, ) -> errors::RouterResult> { - #[cfg(all( - any(feature = "v2", feature = "v1"), - not(feature = "payment_methods_v2") - ))] let payment_method_data = pm .payment_method_data .clone() @@ -5481,12 +5465,6 @@ pub async fn get_bank_account_connector_details( ) .transpose()?; - #[cfg(all(feature = "v2", feature = "payment_methods_v2"))] - let payment_method_data = pm - .payment_method_data - .clone() - .map(|x| x.into_inner().expose().into_inner()); - match payment_method_data { Some(pmd) => match pmd { PaymentMethodsData::Card(_) => Err(errors::ApiErrorResponse::UnprocessableEntity { diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs index 5eb97e6eebe2..fd61fcacf5af 100644 --- a/crates/router/src/core/payments.rs +++ b/crates/router/src/core/payments.rs @@ -1019,7 +1019,7 @@ where .to_validate_request()? .validate_request(&req, &merchant_account)?; - let payment_id = id_type::GlobalPaymentId::generate(state.conf.cell_information.id.clone()); + let payment_id = id_type::GlobalPaymentId::generate(&state.conf.cell_information.id.clone()); tracing::Span::current().record("global_payment_id", payment_id.get_string_repr()); diff --git a/crates/router/src/lib.rs b/crates/router/src/lib.rs index 829216db1dd9..839dd472423a 100644 --- a/crates/router/src/lib.rs +++ b/crates/router/src/lib.rs @@ -132,7 +132,7 @@ pub fn mk_app( .service(routes::Forex::server(state.clone())); } - server_app = server_app.service(routes::Profile::server(state.clone())) + server_app = server_app.service(routes::Profile::server(state.clone())); } server_app = server_app .service(routes::Payments::server(state.clone())) @@ -141,6 +141,11 @@ pub fn mk_app( .service(routes::MerchantConnectorAccount::server(state.clone())) .service(routes::Webhooks::server(state.clone())); + #[cfg(feature = "oltp")] + { + server_app = server_app.service(routes::PaymentMethods::server(state.clone())); + } + #[cfg(feature = "v1")] { server_app = server_app @@ -157,8 +162,6 @@ pub fn mk_app( { server_app = server_app .service(routes::EphemeralKey::server(state.clone())) - .service(routes::Webhooks::server(state.clone())) - .service(routes::PaymentMethods::server(state.clone())) .service(routes::Poll::server(state.clone())) } diff --git a/crates/router/src/routes/app.rs b/crates/router/src/routes/app.rs index bb0c547d7f1d..2abe8d66b255 100644 --- a/crates/router/src/routes/app.rs +++ b/crates/router/src/routes/app.rs @@ -954,6 +954,10 @@ pub struct Customers; impl Customers { pub fn server(state: AppState) -> Scope { let mut route = web::scope("/v2/customers").app_data(web::Data::new(state)); + #[cfg(all(feature = "olap", feature = "v2", feature = "customer_v2"))] + { + route = route.service(web::resource("/list").route(web::get().to(customers_list))) + } #[cfg(all(feature = "oltp", feature = "v2", feature = "customer_v2"))] { route = route @@ -965,10 +969,6 @@ impl Customers { .route(web::delete().to(customers_delete)), ) } - #[cfg(all(feature = "olap", feature = "v2", feature = "customer_v2"))] - { - route = route.service(web::resource("/list").route(web::get().to(customers_list))) - } #[cfg(all(feature = "oltp", feature = "v2", feature = "payment_methods_v2"))] { route = route.service( diff --git a/crates/router/src/services/authentication.rs b/crates/router/src/services/authentication.rs index 724539ad08a0..1967eafd180c 100644 --- a/crates/router/src/services/authentication.rs +++ b/crates/router/src/services/authentication.rs @@ -1323,7 +1323,6 @@ where #[derive(Debug)] pub struct EphemeralKeyAuth; -// #[cfg(feature = "v1")] #[async_trait] impl AuthenticateAndFetch for EphemeralKeyAuth where @@ -2987,43 +2986,6 @@ pub fn get_auth_type_and_flow( Ok((Box::new(HeaderAuth(ApiKeyAuth)), api::AuthFlow::Merchant)) } -#[cfg(feature = "v1")] -pub fn check_client_secret_and_get_auth( - headers: &HeaderMap, - payload: &impl ClientSecretFetch, -) -> RouterResult<( - Box>, - api::AuthFlow, -)> -where - T: SessionStateInfo + Sync + Send, - ApiKeyAuth: AuthenticateAndFetch, - PublishableKeyAuth: AuthenticateAndFetch, -{ - let api_key = get_api_key(headers)?; - if api_key.starts_with("pk_") { - payload - .get_client_secret() - .check_value_present("client_secret") - .map_err(|_| errors::ApiErrorResponse::MissingRequiredField { - field_name: "client_secret", - })?; - return Ok(( - Box::new(HeaderAuth(PublishableKeyAuth)), - api::AuthFlow::Client, - )); - } - - if payload.get_client_secret().is_some() { - return Err(errors::ApiErrorResponse::InvalidRequestData { - message: "client_secret is not a valid parameter".to_owned(), - } - .into()); - } - Ok((Box::new(HeaderAuth(ApiKeyAuth)), api::AuthFlow::Merchant)) -} - -#[cfg(feature = "v2")] pub fn check_client_secret_and_get_auth( headers: &HeaderMap, payload: &impl ClientSecretFetch, @@ -3056,11 +3018,9 @@ where } .into()); } - Ok((Box::new(HeaderAuth(ApiKeyAuth)), api::AuthFlow::Merchant)) } -#[cfg(feature = "v1")] pub async fn get_ephemeral_or_other_auth( headers: &HeaderMap, is_merchant_flow: bool, @@ -3093,7 +3053,6 @@ where } } -#[cfg(feature = "v1")] pub fn is_ephemeral_auth( headers: &HeaderMap, ) -> RouterResult>> { @@ -3106,13 +3065,6 @@ pub fn is_ephemeral_auth( } } -#[cfg(feature = "v2")] -pub fn is_ephemeral_auth( - headers: &HeaderMap, -) -> RouterResult>> { - todo!() -} - pub fn is_jwt_auth(headers: &HeaderMap) -> bool { headers.get(headers::AUTHORIZATION).is_some() || get_cookie_from_header(headers) diff --git a/crates/router/src/types/storage/payment_method.rs b/crates/router/src/types/storage/payment_method.rs index 3214f911f567..bc5f6651b6b5 100644 --- a/crates/router/src/types/storage/payment_method.rs +++ b/crates/router/src/types/storage/payment_method.rs @@ -105,6 +105,10 @@ impl PaymentTokenData { } } +#[cfg(all( + any(feature = "v1", feature = "v2"), + not(feature = "payment_methods_v2") +))] #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] pub struct PaymentMethodListContext { pub card_details: Option, @@ -113,6 +117,38 @@ pub struct PaymentMethodListContext { pub bank_transfer_details: Option, } +#[cfg(all(feature = "v2", feature = "payment_methods_v2"))] +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +pub enum PaymentMethodListContext { + Card { + card_details: api::CardDetailFromLocker, + token_data: Option, + }, + Bank { + token_data: Option, + }, + #[cfg(feature = "payouts")] + BankTransfer { + bank_transfer_details: api::BankPayout, + token_data: Option, + }, + TemporaryToken { + token_data: Option, + }, +} + +#[cfg(all(feature = "v2", feature = "payment_methods_v2"))] +impl PaymentMethodListContext { + pub(crate) fn get_token_data(&self) -> Option { + match self { + Self::Card { token_data, .. } + | Self::Bank { token_data } + | Self::BankTransfer { token_data, .. } + | Self::TemporaryToken { token_data } => token_data.clone(), + } + } +} + #[derive(Debug, serde::Deserialize, serde::Serialize, Clone)] pub struct PaymentMethodStatusTrackingData { pub payment_method_id: String,