From 914cab0d7b5a757e58b4ffe175a30f05ed1aeb1c Mon Sep 17 00:00:00 2001 From: Sahkal Poddar Date: Thu, 22 Aug 2024 20:24:56 +0530 Subject: [PATCH] feat(customer_v2): add route for customer retrieve v2 (#5516) Co-authored-by: Narayan Bhat Co-authored-by: hrithikesh026 Co-authored-by: Prajjwal Kumar Co-authored-by: Sanchith Hegde Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com> Co-authored-by: Sahkal Poddar --- Cargo.lock | 118 +++++++++++--------- api-reference-v2/openapi_spec.json | 7 +- crates/api_models/Cargo.toml | 6 +- crates/api_models/src/customers.rs | 15 +++ crates/api_models/src/events/customer.rs | 49 +++++++- crates/common_utils/Cargo.toml | 4 + crates/common_utils/src/events.rs | 5 + crates/diesel_models/src/query/customers.rs | 1 + crates/router/src/core/customers.rs | 28 +++++ crates/router/src/core/payments/helpers.rs | 25 +++-- crates/router/src/routes/app.rs | 22 +++- crates/router/src/routes/customers.rs | 32 ++++++ crates/router/src/routes/ephemeral_key.rs | 6 + crates/router/src/types/api/customers.rs | 3 + 14 files changed, 247 insertions(+), 74 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0a0448cae4..d2c3baf9fb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -448,7 +448,7 @@ dependencies = [ "common_utils", "error-stack", "euclid", - "indexmap 2.3.0", + "indexmap 2.4.0", "masking", "mime", "nutype", @@ -1890,7 +1890,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.52.4", + "windows-targets 0.52.6", ] [[package]] @@ -2083,7 +2083,7 @@ version = "0.1.0" dependencies = [ "anyhow", "clap", - "indexmap 2.3.0", + "indexmap 2.4.0", "serde", "serde_json", "toml 0.8.12", @@ -3475,7 +3475,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.3.0", + "indexmap 2.4.0", "slab", "tokio 1.37.0", "tokio-util", @@ -3494,7 +3494,7 @@ dependencies = [ "futures-sink", "futures-util", "http 1.1.0", - "indexmap 2.3.0", + "indexmap 2.4.0", "slab", "tokio 1.37.0", "tokio-util", @@ -4017,9 +4017,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" +checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" dependencies = [ "equivalent", "hashbrown 0.14.3", @@ -4709,11 +4709,11 @@ dependencies = [ [[package]] name = "normpath" -version = "1.1.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec60c60a693226186f5d6edf073232bfb6464ed97eb22cf3b01c1e8198fd97f5" +checksum = "c8911957c4b1549ac0dc74e30db9c8b0e66ddcd6d7acc33098f4c63a64a6d7ed" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -6190,7 +6190,7 @@ dependencies = [ "common_utils", "diesel", "error-stack", - "indexmap 2.3.0", + "indexmap 2.4.0", "proc-macro2", "quote", "serde", @@ -6682,9 +6682,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.205" +version = "1.0.208" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33aedb1a7135da52b7c21791455563facbbcc43d0f0f66165b42c21b3dfb150" +checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2" dependencies = [ "serde_derive", ] @@ -6723,9 +6723,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.205" +version = "1.0.208" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692d6f5ac90220161d6774db30c662202721e64aed9058d2c394f451261420c1" +checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf" dependencies = [ "proc-macro2", "quote", @@ -6734,11 +6734,11 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.122" +version = "1.0.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da" +checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed" dependencies = [ - "indexmap 2.3.0", + "indexmap 2.4.0", "itoa", "memchr", "ryu", @@ -6817,7 +6817,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.3.0", + "indexmap 2.4.0", "serde", "serde_derive", "serde_json", @@ -6843,7 +6843,7 @@ version = "0.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48e76bab63c3fd98d27c17f9cbce177f64a91f5e69ac04cafe04e1bb25d1dc3c" dependencies = [ - "indexmap 2.3.0", + "indexmap 2.4.0", "itoa", "libyml", "log", @@ -7118,7 +7118,7 @@ dependencies = [ "futures-util", "hashlink", "hex", - "indexmap 2.3.0", + "indexmap 2.4.0", "log", "memchr", "native-tls", @@ -8060,7 +8060,7 @@ version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" dependencies = [ - "indexmap 2.3.0", + "indexmap 2.4.0", "serde", "serde_spanned", "toml_datetime", @@ -8082,7 +8082,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.3.0", + "indexmap 2.4.0", "serde", "serde_spanned", "toml_datetime", @@ -8095,7 +8095,7 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ - "indexmap 2.3.0", + "indexmap 2.4.0", "toml_datetime", "winnow 0.5.40", ] @@ -8106,7 +8106,7 @@ version = "0.22.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" dependencies = [ - "indexmap 2.3.0", + "indexmap 2.4.0", "serde", "serde_spanned", "toml_datetime", @@ -8518,7 +8518,7 @@ version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "272ebdfbc99111033031d2f10e018836056e4d2c8e2acda76450ec7974269fa7" dependencies = [ - "indexmap 2.3.0", + "indexmap 2.4.0", "serde", "serde_json", "utoipa-gen", @@ -8846,7 +8846,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.6", ] [[package]] @@ -8864,7 +8864,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -8884,17 +8893,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -8905,9 +8915,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -8917,9 +8927,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -8929,9 +8939,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -8941,9 +8957,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -8953,9 +8969,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -8965,9 +8981,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -8977,9 +8993,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" diff --git a/api-reference-v2/openapi_spec.json b/api-reference-v2/openapi_spec.json index 1dcc79c255..757beea4b6 100644 --- a/api-reference-v2/openapi_spec.json +++ b/api-reference-v2/openapi_spec.json @@ -4954,7 +4954,8 @@ "type": "object", "required": [ "merchant_reference_id", - "created_at" + "created_at", + "id" ], "properties": { "merchant_reference_id": { @@ -5032,6 +5033,10 @@ "example": "pm_djh2837dwduh890123", "nullable": true, "maxLength": 64 + }, + "id": { + "type": "string", + "description": "Global id" } } }, diff --git a/crates/api_models/Cargo.toml b/crates/api_models/Cargo.toml index 0134c6c6fc..57b797fa61 100644 --- a/crates/api_models/Cargo.toml +++ b/crates/api_models/Cargo.toml @@ -17,10 +17,10 @@ frm = [] olap = [] openapi = ["common_enums/openapi", "olap", "recon", "dummy_connector", "olap"] recon = [] -v1 = [] -v2 = [] +v1 = ["common_utils/v1"] +v2 = ["common_utils/v2"] business_profile_v2 = [] -customer_v2 = [] +customer_v2 = ["common_utils/customer_v2"] merchant_account_v2 = [] merchant_connector_account_v2 = [] payment_v2 = [] diff --git a/crates/api_models/src/customers.rs b/crates/api_models/src/customers.rs index 1f890b1bf8..6a9f2b6479 100644 --- a/crates/api_models/src/customers.rs +++ b/crates/api_models/src/customers.rs @@ -282,6 +282,8 @@ pub struct CustomerResponse { /// The identifier for the default payment method. #[schema(max_length = 64, example = "pm_djh2837dwduh890123")] pub default_payment_method_id: Option, + /// Global id + pub id: String, } #[cfg(all(feature = "v2", feature = "customer_v2"))] @@ -308,6 +310,19 @@ impl CustomerId { } } +#[cfg(all(feature = "v2", feature = "customer_v2"))] +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct GlobalId { + pub id: String, +} + +#[cfg(all(feature = "v2", feature = "customer_v2"))] +impl GlobalId { + pub fn new(id: String) -> Self { + Self { id } + } +} + #[cfg(all(feature = "v2", feature = "customer_v2"))] #[derive(Clone, Debug, Deserialize, Serialize)] pub struct CustomerId { diff --git a/crates/api_models/src/events/customer.rs b/crates/api_models/src/events/customer.rs index dedc1b82c8..b6fcb9b047 100644 --- a/crates/api_models/src/events/customer.rs +++ b/crates/api_models/src/events/customer.rs @@ -1,9 +1,12 @@ use common_utils::events::{ApiEventMetric, ApiEventsType}; -use crate::customers::{ - CustomerDeleteResponse, CustomerId, CustomerRequest, CustomerResponse, CustomerUpdateRequest, -}; +#[cfg(all(feature = "v2", feature = "customer_v2"))] +use crate::customers::GlobalId; +#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))] +use crate::customers::{CustomerDeleteResponse, CustomerId}; +use crate::customers::{CustomerRequest, CustomerResponse, CustomerUpdateRequest}; +#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))] impl ApiEventMetric for CustomerDeleteResponse { fn get_api_event_type(&self) -> Option { Some(ApiEventsType::Customer { @@ -12,6 +15,7 @@ impl ApiEventMetric for CustomerDeleteResponse { } } +#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))] impl ApiEventMetric for CustomerRequest { fn get_api_event_type(&self) -> Option { self.get_merchant_reference_id() @@ -20,6 +24,16 @@ impl ApiEventMetric for CustomerRequest { } } +#[cfg(all(feature = "v2", feature = "customer_v2"))] +impl ApiEventMetric for CustomerRequest { + fn get_api_event_type(&self) -> Option { + Some(ApiEventsType::Customer { + id: "temp_id".to_string(), + }) + } +} + +#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))] impl ApiEventMetric for CustomerResponse { fn get_api_event_type(&self) -> Option { self.get_merchant_reference_id() @@ -28,6 +42,16 @@ impl ApiEventMetric for CustomerResponse { } } +#[cfg(all(feature = "v2", feature = "customer_v2"))] +impl ApiEventMetric for CustomerResponse { + fn get_api_event_type(&self) -> Option { + Some(ApiEventsType::Customer { + id: self.id.clone(), + }) + } +} + +#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))] impl ApiEventMetric for CustomerId { fn get_api_event_type(&self) -> Option { Some(ApiEventsType::Customer { @@ -36,6 +60,16 @@ impl ApiEventMetric for CustomerId { } } +#[cfg(all(feature = "v2", feature = "customer_v2"))] +impl ApiEventMetric for GlobalId { + fn get_api_event_type(&self) -> Option { + Some(ApiEventsType::Customer { + id: self.id.clone(), + }) + } +} + +#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))] impl ApiEventMetric for CustomerUpdateRequest { fn get_api_event_type(&self) -> Option { self.get_merchant_reference_id() @@ -43,4 +77,13 @@ impl ApiEventMetric for CustomerUpdateRequest { .map(|cid| ApiEventsType::Customer { customer_id: cid }) } } + +#[cfg(all(feature = "v2", feature = "customer_v2"))] +impl ApiEventMetric for CustomerUpdateRequest { + fn get_api_event_type(&self) -> Option { + Some(ApiEventsType::Customer { + id: "temo_id".to_string(), + }) + } +} // These needs to be fixed for v2 diff --git a/crates/common_utils/Cargo.toml b/crates/common_utils/Cargo.toml index 8507095119..c53fa2c003 100644 --- a/crates/common_utils/Cargo.toml +++ b/crates/common_utils/Cargo.toml @@ -8,6 +8,7 @@ readme = "README.md" license.workspace = true [features] +default = ["v1"] keymanager = ["dep:router_env"] keymanager_mtls = ["reqwest/rustls-tls"] encryption_service = ["dep:router_env"] @@ -16,6 +17,9 @@ async_ext = ["dep:async-trait", "dep:futures"] logs = ["dep:router_env"] metrics = ["dep:router_env", "dep:futures"] payouts = ["common_enums/payouts"] +v1 = [] +v2 = [] +customer_v2 = [] [dependencies] async-trait = { version = "0.1.79", optional = true } diff --git a/crates/common_utils/src/events.rs b/crates/common_utils/src/events.rs index ac4b9c42a4..4377714396 100644 --- a/crates/common_utils/src/events.rs +++ b/crates/common_utils/src/events.rs @@ -27,6 +27,11 @@ pub enum ApiEventsType { payment_method: Option, payment_method_type: Option, }, + #[cfg(all(feature = "v2", feature = "customer_v2"))] + Customer { + id: String, + }, + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))] Customer { customer_id: id_type::CustomerId, }, diff --git a/crates/diesel_models/src/query/customers.rs b/crates/diesel_models/src/query/customers.rs index 568e1f4a9a..337679484c 100644 --- a/crates/diesel_models/src/query/customers.rs +++ b/crates/diesel_models/src/query/customers.rs @@ -23,6 +23,7 @@ impl CustomerNew { } } +// #[cfg(all(feature = "v2", feature = "customer_v2"))] impl Customer { #[cfg(all(feature = "v2", feature = "customer_v2"))] pub async fn update_by_id( diff --git a/crates/router/src/core/customers.rs b/crates/router/src/core/customers.rs index 9036c4e0b3..4e45e48cfa 100644 --- a/crates/router/src/core/customers.rs +++ b/crates/router/src/core/customers.rs @@ -439,6 +439,7 @@ pub async fn retrieve_customer( ) -> errors::CustomerResponse { let db = state.store.as_ref(); let key_manager_state = &(&state).into(); + let response = db .find_customer_by_customer_id_merchant_id( key_manager_state, @@ -462,6 +463,33 @@ pub async fn retrieve_customer( )) } +#[cfg(all(feature = "v2", feature = "customer_v2"))] +#[instrument(skip(state))] +pub async fn retrieve_customer( + state: SessionState, + merchant_account: domain::MerchantAccount, + key_store: domain::MerchantKeyStore, + req: customers::GlobalId, +) -> errors::CustomerResponse { + let db = state.store.as_ref(); + let key_manager_state = &(&state).into(); + + let response = db + .find_customer_by_global_id( + key_manager_state, + &req.id, + merchant_account.get_id(), + &key_store, + merchant_account.storage_scheme, + ) + .await + .switch()?; + + Ok(services::ApplicationResponse::Json( + customers::CustomerResponse::foreign_from(response), + )) +} + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))] #[instrument(skip(state))] pub async fn list_customers( diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index ed30a7ff49..3715adefed 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -1437,6 +1437,19 @@ pub(crate) async fn get_payment_method_create_request( } } +#[cfg(all(feature = "v2", feature = "customer_v2"))] +pub async fn get_customer_from_details( + _state: &SessionState, + _customer_id: Option, + _merchant_id: &id_type::MerchantId, + _payment_data: &mut PaymentData, + _merchant_key_store: &domain::MerchantKeyStore, + _storage_scheme: enums::MerchantStorageScheme, +) -> CustomResult, errors::StorageError> { + todo!() +} + +#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))] pub async fn get_customer_from_details( state: &SessionState, customer_id: Option, @@ -1449,7 +1462,6 @@ pub async fn get_customer_from_details( None => Ok(None), Some(customer_id) => { let db = &*state.store; - #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))] let customer = db .find_customer_optional_by_customer_id_merchant_id( &state.into(), @@ -1460,17 +1472,6 @@ pub async fn get_customer_from_details( ) .await?; - #[cfg(all(feature = "v2", feature = "customer_v2"))] - let customer = db - .find_optional_by_merchant_id_merchant_reference_id( - &state.into(), - &customer_id, - merchant_id, - merchant_key_store, - storage_scheme, - ) - .await?; - payment_data.email = payment_data.email.clone().or_else(|| { customer.as_ref().and_then(|inner| { inner diff --git a/crates/router/src/routes/app.rs b/crates/router/src/routes/app.rs index d52c1cef45..d8e1614110 100644 --- a/crates/router/src/routes/app.rs +++ b/crates/router/src/routes/app.rs @@ -30,6 +30,12 @@ use super::blocklist; use super::currency; #[cfg(feature = "dummy_connector")] use super::dummy_connector::*; +#[cfg(all( + any(feature = "v1", feature = "v2"), + not(feature = "customer_v2"), + feature = "oltp" +))] +use super::ephemeral_key::*; #[cfg(any(feature = "olap", feature = "oltp"))] use super::payment_methods::*; #[cfg(feature = "payouts")] @@ -48,6 +54,8 @@ use super::poll::retrieve_poll_status; use super::routing; #[cfg(feature = "olap")] use super::verification::{apple_pay_merchant_registration, retrieve_apple_pay_verified_domains}; +#[cfg(feature = "oltp")] +use super::webhooks::*; #[cfg(feature = "olap")] use super::{ admin::*, api_keys::*, apple_pay_certificates_migration, connector_onboarding::*, disputes::*, @@ -56,8 +64,6 @@ use super::{ use super::{cache::*, health::*}; #[cfg(any(feature = "olap", feature = "oltp"))] use super::{configs::*, customers::*, mandates::*, payments::*, refunds::*}; -#[cfg(feature = "oltp")] -use super::{ephemeral_key::*, webhooks::*}; #[cfg(feature = "olap")] pub use crate::analytics::opensearch::OpenSearchClient; #[cfg(feature = "olap")] @@ -886,7 +892,11 @@ impl Customers { { route = route .service(web::resource("").route(web::post().to(customers_create))) - .service(web::resource("/{id}").route(web::put().to(customers_update))) + .service( + web::resource("/{id}") + .route(web::put().to(customers_update)) + .route(web::post().to(customers_retrieve)), + ) } #[cfg(all(feature = "oltp", feature = "v2", feature = "payment_methods_v2"))] { @@ -1260,7 +1270,11 @@ impl MerchantConnectorAccount { pub struct EphemeralKey; -#[cfg(feature = "oltp")] +#[cfg(all( + any(feature = "v1", feature = "v2"), + not(feature = "customer_v2"), + feature = "oltp" +))] impl EphemeralKey { pub fn server(config: AppState) -> Scope { web::scope("/ephemeral_keys") diff --git a/crates/router/src/routes/customers.rs b/crates/router/src/routes/customers.rs index a84214374c..20d6539bb0 100644 --- a/crates/router/src/routes/customers.rs +++ b/crates/router/src/routes/customers.rs @@ -78,6 +78,38 @@ pub async fn customers_retrieve( .await } +#[cfg(all(feature = "v2", feature = "customer_v2"))] +#[instrument(skip_all, fields(flow = ?Flow::CustomersRetrieve))] +pub async fn customers_retrieve( + state: web::Data, + req: HttpRequest, + path: web::Path, +) -> HttpResponse { + let flow = Flow::CustomersRetrieve; + + let payload = web::Json(customers::GlobalId::new(path.into_inner())).into_inner(); + + let auth = if auth::is_jwt_auth(req.headers()) { + Box::new(auth::JWTAuth(Permission::CustomerRead)) + } else { + match auth::is_ephemeral_auth(req.headers()) { + Ok(auth) => auth, + Err(err) => return api::log_and_return_error_response(err), + } + }; + + Box::pin(api::server_wrap( + flow, + state, + &req, + payload, + |state, auth, req, _| retrieve_customer(state, auth.merchant_account, auth.key_store, req), + &*auth, + api_locking::LockAction::NotApplicable, + )) + .await +} + #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))] #[instrument(skip_all, fields(flow = ?Flow::CustomersList))] pub async fn customers_list(state: web::Data, req: HttpRequest) -> HttpResponse { diff --git a/crates/router/src/routes/ephemeral_key.rs b/crates/router/src/routes/ephemeral_key.rs index 893b2e5a09..cec7439940 100644 --- a/crates/router/src/routes/ephemeral_key.rs +++ b/crates/router/src/routes/ephemeral_key.rs @@ -1,13 +1,18 @@ +#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))] use actix_web::{web, HttpRequest, HttpResponse}; +#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))] use router_env::{instrument, tracing, Flow}; +#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))] use super::AppState; +#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))] use crate::{ core::{api_locking, payments::helpers}, services::{api, authentication as auth}, types::api::customers, }; +#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))] #[instrument(skip_all, fields(flow = ?Flow::EphemeralKeyCreate))] pub async fn ephemeral_key_create( state: web::Data, @@ -34,6 +39,7 @@ pub async fn ephemeral_key_create( .await } +#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))] #[instrument(skip_all, fields(flow = ?Flow::EphemeralKeyDelete))] pub async fn ephemeral_key_delete( state: web::Data, diff --git a/crates/router/src/types/api/customers.rs b/crates/router/src/types/api/customers.rs index 2076ad60c0..b72b364720 100644 --- a/crates/router/src/types/api/customers.rs +++ b/crates/router/src/types/api/customers.rs @@ -1,4 +1,6 @@ use api_models::customers; +#[cfg(all(feature = "v2", feature = "customer_v2"))] +pub use api_models::customers::GlobalId; pub use api_models::customers::{ CustomerDeleteResponse, CustomerId, CustomerRequest, CustomerUpdateRequest, UpdateCustomerId, }; @@ -58,6 +60,7 @@ impl ForeignFrom for CustomerResponse { default_billing_address: None, default_shipping_address: None, default_payment_method_id: cust.default_payment_method_id, + id: cust.id, } .into() }