Bug: feat(core): Add V2 Authentication to all available endpoints



Introduces V2 authentication mechanisms for various admin and client-side APIs :
- [ ] Add V2AdminApiAuth and modified AdminApiAuthWithMerchantIdFromRoute for V2
- [ ] Add  V2ApiKeyAuth , V2AdminApiAuth and V2ClientAuth to the endpoints
- [ ] Refactor functions to support V2 Auth as well as V1 Auth
diff --git a/crates/router/src/core/errors.rs b/crates/router/src/core/errors.rs
index b32fe76f5ec..d82bef27d1f 100644
--- a/crates/router/src/core/errors.rs
+++ b/crates/router/src/core/errors.rs
@@ -483,6 +483,6 @@ pub enum RevenueRecoveryError {
     PaymentIntentCreateFailed,
     #[error("Source verification failed for billing connector")]
     WebhookAuthenticationFailed,
-    #[error("Payment merchant connector account not found using acccount reference id")]
+    #[error("Payment merchant connector account not found using account reference id")]
     PaymentMerchantConnectorAccountNotFound,
 }
diff --git a/crates/router/src/routes/admin.rs b/crates/router/src/routes/admin.rs
index a38a9df72be..3cd959838a5 100644
--- a/crates/router/src/routes/admin.rs
+++ b/crates/router/src/routes/admin.rs
@@ -8,7 +8,7 @@ use crate::{
     types::api::admin,
 };
 
-#[cfg(feature = "olap")]
+#[cfg(all(feature = "olap", feature = "v1"))]
 #[instrument(skip_all, fields(flow = ?Flow::OrganizationCreate))]
 pub async fn organization_create(
     state: web::Data<AppState>,
@@ -27,8 +27,26 @@ pub async fn organization_create(
     ))
     .await
 }
-
-#[cfg(feature = "olap")]
+#[cfg(all(feature = "olap", feature = "v2"))]
+#[instrument(skip_all, fields(flow = ?Flow::OrganizationCreate))]
+pub async fn organization_create(
+    state: web::Data<AppState>,
+    req: HttpRequest,
+    json_payload: web::Json<admin::OrganizationCreateRequest>,
+) -> HttpResponse {
+    let flow = Flow::OrganizationCreate;
+    Box::pin(api::server_wrap(
+        flow,
+        state,
+        &req,
+        json_payload.into_inner(),
+        |state, _, req, _| create_organization(state, req),
+        &auth::V2AdminApiAuth,
+        api_locking::LockAction::NotApplicable,
+    ))
+    .await
+}
+#[cfg(all(feature = "olap", feature = "v1"))]
 #[instrument(skip_all, fields(flow = ?Flow::OrganizationUpdate))]
 pub async fn organization_update(
     state: web::Data<AppState>,
@@ -59,8 +77,38 @@ pub async fn organization_update(
     ))
     .await
 }
-
-#[cfg(feature = "olap")]
+#[cfg(all(feature = "olap", feature = "v2"))]
+#[instrument(skip_all, fields(flow = ?Flow::OrganizationUpdate))]
+pub async fn organization_update(
+    state: web::Data<AppState>,
+    req: HttpRequest,
+    org_id: web::Path<common_utils::id_type::OrganizationId>,
+    json_payload: web::Json<admin::OrganizationUpdateRequest>,
+) -> HttpResponse {
+    let flow = Flow::OrganizationUpdate;
+    let organization_id = org_id.into_inner();
+    let org_id = admin::OrganizationId {
+        organization_id: organization_id.clone(),
+    };
+    Box::pin(api::server_wrap(
+        flow,
+        state,
+        &req,
+        json_payload.into_inner(),
+        |state, _, req, _| update_organization(state, org_id.clone(), req),
+        auth::auth_type(
+            &auth::V2AdminApiAuth,
+            &auth::JWTAuthOrganizationFromRoute {
+                organization_id,
+                required_permission: Permission::OrganizationAccountWrite,
+            },
+            req.headers(),
+        ),
+        api_locking::LockAction::NotApplicable,
+    ))
+    .await
+}
+#[cfg(all(feature = "olap", feature = "v1"))]
 #[instrument(skip_all, fields(flow = ?Flow::OrganizationRetrieve))]
 pub async fn organization_retrieve(
     state: web::Data<AppState>,
@@ -92,6 +140,38 @@ pub async fn organization_retrieve(
     .await
 }
 
+#[cfg(all(feature = "olap", feature = "v2"))]
+#[instrument(skip_all, fields(flow = ?Flow::OrganizationRetrieve))]
+pub async fn organization_retrieve(
+    state: web::Data<AppState>,
+    req: HttpRequest,
+    org_id: web::Path<common_utils::id_type::OrganizationId>,
+) -> HttpResponse {
+    let flow = Flow::OrganizationRetrieve;
+    let organization_id = org_id.into_inner();
+    let payload = admin::OrganizationId {
+        organization_id: organization_id.clone(),
+    };
+
+    Box::pin(api::server_wrap(
+        flow,
+        state,
+        &req,
+        payload,
+        |state, _, req, _| get_organization(state, req),
+        auth::auth_type(
+            &auth::V2AdminApiAuth,
+            &auth::JWTAuthOrganizationFromRoute {
+                organization_id,
+                required_permission: Permission::OrganizationAccountRead,
+            },
+            req.headers(),
+        ),
+        api_locking::LockAction::NotApplicable,
+    ))
+    .await
+}
+
 #[cfg(all(feature = "olap", feature = "v1"))]
 #[instrument(skip_all, fields(flow = ?Flow::MerchantsAccountCreate))]
 pub async fn merchant_account_create(
@@ -144,15 +224,51 @@ pub async fn merchant_account_create(
         &req,
         new_request_payload_with_org_id,
         |state, _, req, _| create_merchant_account(state, req),
-        &auth::AdminApiAuth,
+        &auth::V2AdminApiAuth,
         api_locking::LockAction::NotApplicable,
     ))
     .await
 }
 
+#[cfg(feature = "v1")]
+#[instrument(skip_all, fields(flow = ?Flow::MerchantsAccountRetrieve))]
+pub async fn retrieve_merchant_account(
+    state: web::Data<AppState>,
+    req: HttpRequest,
+    mid: web::Path<common_utils::id_type::MerchantId>,
+) -> HttpResponse {
+    let flow = Flow::MerchantsAccountRetrieve;
+    let merchant_id = mid.into_inner();
+    let payload = admin::MerchantId {
+        merchant_id: merchant_id.clone(),
+    };
+    api::server_wrap(
+        flow,
+        state,
+        &req,
+        payload,
+        |state, _, req, _| get_merchant_account(state, req, None),
+        auth::auth_type(
+            &auth::AdminApiAuth,
+            &auth::JWTAuthMerchantFromRoute {
+                merchant_id,
+                // This should ideally be MerchantAccountRead, but since FE is calling this API for
+                // profile level users currently keeping this as ProfileAccountRead. FE is removing
+                // this API call for profile level users.
+                // TODO: Convert this to MerchantAccountRead once FE changes are done.
+                required_permission: Permission::ProfileAccountRead,
+            },
+            req.headers(),
+        ),
+        api_locking::LockAction::NotApplicable,
+    )
+    .await
+}
+
 /// Merchant Account - Retrieve
 ///
 /// Retrieve a merchant account details.
+#[cfg(feature = "v2")]
 #[instrument(skip_all, fields(flow = ?Flow::MerchantsAccountRetrieve))]
 pub async fn retrieve_merchant_account(
     state: web::Data<AppState>,
@@ -171,7 +287,7 @@ pub async fn retrieve_merchant_account(
         payload,
         |state, _, req, _| get_merchant_account(state, req, None),
         auth::auth_type(
-            &auth::AdminApiAuth,
+            &auth::V2AdminApiAuth,
             &auth::JWTAuthMerchantFromRoute {
                 merchant_id,
                 // This should ideally be MerchantAccountRead, but since FE is calling this API for
@@ -207,7 +323,7 @@ pub async fn merchant_account_list(
         organization_id,
         |state, _, request, _| list_merchant_account(state, request),
         auth::auth_type(
-            &auth::AdminApiAuth,
+            &auth::V2AdminApiAuth,
             &auth::JWTAuthMerchantFromHeader {
                 required_permission: Permission::MerchantAccountRead,
             },
@@ -248,6 +364,35 @@ pub async fn merchant_account_list(
 /// Merchant Account - Update
 ///
 /// To update an existing merchant account. Helpful in updating merchant details such as email, contact details, or other configuration details like webhook, routing algorithm etc
+#[cfg(feature = "v2")]
+#[instrument(skip_all, fields(flow = ?Flow::MerchantsAccountUpdate))]
+pub async fn update_merchant_account(
+    state: web::Data<AppState>,
+    req: HttpRequest,
+    mid: web::Path<common_utils::id_type::MerchantId>,
+    json_payload: web::Json<admin::MerchantAccountUpdate>,
+) -> HttpResponse {
+    let flow = Flow::MerchantsAccountUpdate;
+    let merchant_id = mid.into_inner();
+    Box::pin(api::server_wrap(
+        flow,
+        state,
+        &req,
+        json_payload.into_inner(),
+        |state, _, req, _| merchant_account_update(state, &merchant_id, None, req),
+        auth::auth_type(
+            &auth::V2AdminApiAuth,
+            &auth::JWTAuthMerchantFromRoute {
+                merchant_id: merchant_id.clone(),
+                required_permission: Permission::MerchantAccountWrite,
+            },
+            req.headers(),
+        ),
+        api_locking::LockAction::NotApplicable,
+    ))
+    .await
+}
+#[cfg(feature = "v1")]
 #[instrument(skip_all, fields(flow = ?Flow::MerchantsAccountUpdate))]
 pub async fn update_merchant_account(
     state: web::Data<AppState>,
@@ -279,6 +424,30 @@ pub async fn update_merchant_account(
 /// Merchant Account - Delete
 ///
 /// To delete a merchant account
+#[cfg(feature = "v2")]
+#[instrument(skip_all, fields(flow = ?Flow::MerchantsAccountDelete))]
+pub async fn delete_merchant_account(
+    state: web::Data<AppState>,
+    req: HttpRequest,
+    mid: web::Path<common_utils::id_type::MerchantId>,
+) -> HttpResponse {
+    let flow = Flow::MerchantsAccountDelete;
+    let mid = mid.into_inner();
+
+    let payload = web::Json(admin::MerchantId { merchant_id: mid }).into_inner();
+    api::server_wrap(
+        flow,
+        state,
+        &req,
+        payload,
+        |state, _, req, _| merchant_account_delete(state, req.merchant_id),
+        &auth::V2AdminApiAuth,
+        api_locking::LockAction::NotApplicable,
+    )
+    .await
+}
+
+#[cfg(feature = "v1")]
 #[instrument(skip_all, fields(flow = ?Flow::MerchantsAccountDelete))]
 pub async fn delete_merchant_account(
     state: web::Data<AppState>,
@@ -712,7 +881,7 @@ pub async fn connector_update(
         payload,
         |state, _, req, _| update_connector(state, &merchant_id, None, &id, req),
         auth::auth_type(
-            &auth::AdminApiAuth,
+            &auth::V2AdminApiAuth,
             &auth::JWTAuthMerchantFromRoute {
                 merchant_id: merchant_id.clone(),
                 required_permission: Permission::MerchantConnectorWrite,
diff --git a/crates/router/src/routes/api_keys.rs b/crates/router/src/routes/api_keys.rs
index 8c0b7137662..911617753d4 100644
--- a/crates/router/src/routes/api_keys.rs
+++ b/crates/router/src/routes/api_keys.rs
@@ -268,7 +268,7 @@ pub async fn api_key_revoke(
         (&merchant_id, &key_id),
         |state, _, (merchant_id, key_id), _| api_keys::revoke_api_key(state, merchant_id, key_id),
         auth::auth_type(
-            &auth::AdminApiAuth,
+            &auth::V2AdminApiAuth,
             &auth::JWTAuthMerchantFromRoute {
                 merchant_id: merchant_id.clone(),
                 required_permission: Permission::MerchantApiKeyWrite,
diff --git a/crates/router/src/routes/customers.rs b/crates/router/src/routes/customers.rs
index c793e3c85e5..c9ff466af00 100644
--- a/crates/router/src/routes/customers.rs
+++ b/crates/router/src/routes/customers.rs
@@ -8,7 +8,34 @@ use crate::{
     services::{api, authentication as auth, authorization::permissions::Permission},
     types::api::customers,
 };
-
+#[cfg(all(feature = "v2", feature = "customer_v2"))]
+#[instrument(skip_all, fields(flow = ?Flow::CustomersCreate))]
+pub async fn customers_create(
+    state: web::Data<AppState>,
+    req: HttpRequest,
+    json_payload: web::Json<customers::CustomerRequest>,
+) -> HttpResponse {
+    let flow = Flow::CustomersCreate;
+    Box::pin(api::server_wrap(
+        flow,
+        state,
+        &req,
+        json_payload.into_inner(),
+        |state, auth: auth::AuthenticationData, req, _| {
+            create_customer(state, auth.merchant_account, auth.key_store, req)
+        },
+        auth::auth_type(
+            &auth::V2ApiKeyAuth,
+            &auth::JWTAuth {
+                permission: Permission::MerchantCustomerWrite,
+            },
+            req.headers(),
+        ),
+        api_locking::LockAction::NotApplicable,
+    ))
+    .await
+}
+#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))]
 #[instrument(skip_all, fields(flow = ?Flow::CustomersCreate))]
 pub async fn customers_create(
     state: web::Data<AppState>,
@@ -115,7 +142,42 @@ pub async fn customers_retrieve(
     ))
     .await
 }
+#[cfg(all(feature = "v2", feature = "customer_v2"))]
+#[instrument(skip_all, fields(flow = ?Flow::CustomersList))]
+pub async fn customers_list(
+    state: web::Data<AppState>,
+    req: HttpRequest,
+    query: web::Query<customers::CustomerListRequest>,
+) -> HttpResponse {
+    let flow = Flow::CustomersList;
+    let payload = query.into_inner();
 
+    api::server_wrap(
+        flow,
+        state,
+        &req,
+        payload,
+        |state, auth: auth::AuthenticationData, request, _| {
+            list_customers(
+                state,
+                auth.merchant_account.get_id().to_owned(),
+                None,
+                auth.key_store,
+                request,
+            )
+        },
+        auth::auth_type(
+            &auth::V2ApiKeyAuth,
+            &auth::JWTAuth {
+                permission: Permission::MerchantCustomerRead,
+            },
+            req.headers(),
+        ),
+        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<AppState>,
@@ -219,7 +281,7 @@ pub async fn customers_update(
             )
         },
         auth::auth_type(
-            &auth::HeaderAuth(auth::ApiKeyAuth),
+            &auth::V2ApiKeyAuth,
             &auth::JWTAuth {
                 permission: Permission::MerchantCustomerWrite,
             },
@@ -249,7 +311,7 @@ pub async fn customers_delete(
             delete_customer(state, auth.merchant_account, id, auth.key_store)
         },
         auth::auth_type(
-            &auth::HeaderAuth(auth::ApiKeyAuth),
+            &auth::V2ApiKeyAuth,
             &auth::JWTAuth {
                 permission: Permission::MerchantCustomerWrite,
             },
diff --git a/crates/router/src/routes/ephemeral_key.rs b/crates/router/src/routes/ephemeral_key.rs
index 64b46eb2f55..5a802cb4c5a 100644
--- a/crates/router/src/routes/ephemeral_key.rs
+++ b/crates/router/src/routes/ephemeral_key.rs
@@ -78,7 +78,7 @@ pub async fn client_secret_create(
                 req.headers(),
             )
         },
-        &auth::HeaderAuth(auth::ApiKeyAuth),
+        &auth::V2ApiKeyAuth,
         api_locking::LockAction::NotApplicable,
     ))
     .await
@@ -99,7 +99,7 @@ pub async fn client_secret_delete(
         &req,
         payload,
         |state, _: auth::AuthenticationData, req, _| helpers::delete_client_secret(state, req),
-        &auth::HeaderAuth(auth::ApiKeyAuth),
+        &auth::V2ApiKeyAuth,
         api_locking::LockAction::NotApplicable,
     ))
     .await
diff --git a/crates/router/src/routes/payment_methods.rs b/crates/router/src/routes/payment_methods.rs
index 92f16b6c4c7..ec5e1dacf0a 100644
--- a/crates/router/src/routes/payment_methods.rs
+++ b/crates/router/src/routes/payment_methods.rs
@@ -95,7 +95,7 @@ pub async fn create_payment_method_api(
             ))
             .await
         },
-        &auth::HeaderAuth(auth::ApiKeyAuth),
+        &auth::V2ApiKeyAuth,
         api_locking::LockAction::NotApplicable,
     ))
     .await
@@ -214,7 +214,7 @@ pub async fn payment_method_retrieve_api(
                 auth.merchant_account,
             )
         },
-        &auth::HeaderAuth(auth::ApiKeyAuth),
+        &auth::V2ApiKeyAuth,
         api_locking::LockAction::NotApplicable,
     ))
     .await
@@ -246,7 +246,7 @@ pub async fn payment_method_delete_api(
                 auth.merchant_account,
             )
         },
-        &auth::HeaderAuth(auth::ApiKeyAuth),
+        &auth::V2ApiKeyAuth,
         api_locking::LockAction::NotApplicable,
     ))
     .await
@@ -613,7 +613,7 @@ pub async fn list_customer_payment_method_api(
             )
         },
         auth::auth_type(
-            &auth::HeaderAuth(auth::ApiKeyAuth),
+            &auth::V2ApiKeyAuth,
             &auth::JWTAuth {
                 permission: Permission::MerchantCustomerRead,
             },
diff --git a/crates/router/src/routes/payments.rs b/crates/router/src/routes/payments.rs
index 9708f34c53c..4e670a594a5 100644
--- a/crates/router/src/routes/payments.rs
+++ b/crates/router/src/routes/payments.rs
@@ -147,9 +147,9 @@ pub async fn payments_create_intent(
             )
         },
         match env::which() {
-            env::Env::Production => &auth::HeaderAuth(auth::ApiKeyAuth),
+            env::Env::Production => &auth::V2ApiKeyAuth,
             _ => auth::auth_type(
-                &auth::HeaderAuth(auth::ApiKeyAuth),
+                &auth::V2ApiKeyAuth,
                 &auth::JWTAuth {
                     permission: Permission::ProfilePaymentWrite,
                 },
@@ -210,7 +210,7 @@ pub async fn payments_get_intent(
                 auth.platform_merchant_account,
             )
         },
-        &auth::HeaderAuth(auth::ApiKeyAuth),
+        &auth::V2ApiKeyAuth,
         api_locking::LockAction::NotApplicable,
     ))
     .await
@@ -249,9 +249,9 @@ pub async fn payments_create_and_confirm_intent(
             )
         },
         match env::which() {
-            env::Env::Production => &auth::HeaderAuth(auth::ApiKeyAuth),
+            env::Env::Production => &auth::V2ApiKeyAuth,
             _ => auth::auth_type(
-                &auth::HeaderAuth(auth::ApiKeyAuth),
+                &auth::V2ApiKeyAuth,
                 &auth::JWTAuth {
                     permission: Permission::ProfilePaymentWrite,
                 },
@@ -313,7 +313,7 @@ pub async fn payments_update_intent(
                 auth.platform_merchant_account,
             )
         },
-        &auth::HeaderAuth(auth::ApiKeyAuth),
+        &auth::V2ApiKeyAuth,
         api_locking::LockAction::NotApplicable,
     ))
     .await
@@ -825,7 +825,7 @@ pub async fn payments_connector_session(
     tracing::Span::current().record("payment_id", global_payment_id.get_string_repr());
 
     let internal_payload = internal_payload_types::PaymentsGenericRequestWithResourceId {
-        global_payment_id,
+        global_payment_id: global_payment_id.clone(),
         payload: json_payload.into_inner(),
     };
 
@@ -868,7 +868,9 @@ pub async fn payments_connector_session(
                 auth.platform_merchant_account,
             )
         },
-        &auth::HeaderAuth(auth::PublishableKeyAuth),
+        &auth::V2ClientAuth(common_utils::types::authentication::ResourceId::Payment(
+            global_payment_id,
+        )),
         locking_action,
     ))
     .await
@@ -1247,7 +1249,7 @@ pub async fn payments_list(
             payments::list_payments(state, auth.merchant_account, auth.key_store, req)
         },
         auth::auth_type(
-            &auth::HeaderAuth(auth::ApiKeyAuth),
+            &auth::V2ApiKeyAuth,
             &auth::JWTAuth {
                 permission: Permission::MerchantPaymentRead,
             },
@@ -2423,7 +2425,7 @@ pub async fn payment_confirm_intent(
     tracing::Span::current().record("payment_id", global_payment_id.get_string_repr());
 
     let internal_payload = internal_payload_types::PaymentsGenericRequestWithResourceId {
-        global_payment_id,
+        global_payment_id: global_payment_id.clone(),
         payload: json_payload.into_inner(),
     };
 
@@ -2468,7 +2470,9 @@ pub async fn payment_confirm_intent(
             ))
             .await
         },
-        &auth::PublishableKeyAuth,
+        &auth::V2ClientAuth(common_utils::types::authentication::ResourceId::Payment(
+            global_payment_id,
+        )),
         locking_action,
     ))
     .await
@@ -2540,7 +2544,7 @@ pub async fn proxy_confirm_intent(
                 header_payload.clone(),
             ))
         },
-        &auth::HeaderAuth(auth::ApiKeyAuth),
+        &auth::V2ApiKeyAuth,
         locking_action,
     ))
     .await
@@ -2611,7 +2615,7 @@ pub async fn payment_status(
             .await
         },
         auth::auth_type(
-            &auth::HeaderAuth(auth::ApiKeyAuth),
+            &auth::V2ApiKeyAuth,
             &auth::JWTAuth {
                 permission: Permission::ProfilePaymentRead,
             },
@@ -2657,7 +2661,7 @@ pub async fn payment_get_intent_using_merchant_reference_id(
             ))
             .await
         },
-        &auth::HeaderAuth(auth::ApiKeyAuth),
+        &auth::V2ApiKeyAuth,
         api_locking::LockAction::NotApplicable,
     ))
     .await
@@ -2776,7 +2780,7 @@ pub async fn payments_capture(
             .await
         },
         auth::auth_type(
-            &auth::HeaderAuth(auth::ApiKeyAuth),
+            &auth::V2ApiKeyAuth,
             &auth::JWTAuth {
                 permission: Permission::ProfileAccountWrite,
             },
@@ -2802,7 +2806,7 @@ pub async fn list_payment_methods(
     tracing::Span::current().record("payment_id", global_payment_id.get_string_repr());
 
     let internal_payload = internal_payload_types::PaymentsGenericRequestWithResourceId {
-        global_payment_id,
+        global_payment_id: global_payment_id.clone(),
         payload,
     };
 
@@ -2829,7 +2833,9 @@ pub async fn list_payment_methods(
                 &header_payload,
             )
         },
-        &auth::PublishableKeyAuth,
+        &auth::V2ClientAuth(common_utils::types::authentication::ResourceId::Payment(
+            global_payment_id,
+        )),
         api_locking::LockAction::NotApplicable,
     ))
     .await
diff --git a/crates/router/src/routes/routing.rs b/crates/router/src/routes/routing.rs
index ac0f997a278..04a0d331688 100644
--- a/crates/router/src/routes/routing.rs
+++ b/crates/router/src/routes/routing.rs
@@ -82,7 +82,7 @@ pub async fn routing_create_config(
         },
         #[cfg(not(feature = "release"))]
         auth::auth_type(
-            &auth::HeaderAuth(auth::ApiKeyAuth),
+            &auth::V2ApiKeyAuth,
             &auth::JWTAuth {
                 permission: Permission::ProfileRoutingWrite,
             },
@@ -170,7 +170,7 @@ pub async fn routing_link_config(
         },
         #[cfg(not(feature = "release"))]
         auth::auth_type(
-            &auth::ApiKeyAuth,
+            &auth::V2ApiKeyAuth,
             &auth::JWTAuthProfileFromRoute {
                 profile_id: wrapper.profile_id,
                 required_permission: Permission::MerchantRoutingWrite,
@@ -252,7 +252,7 @@ pub async fn routing_retrieve_config(
         },
         #[cfg(not(feature = "release"))]
         auth::auth_type(
-            &auth::HeaderAuth(auth::ApiKeyAuth),
+            &auth::V2ApiKeyAuth,
             &auth::JWTAuth {
                 permission: Permission::ProfileRoutingRead,
             },
@@ -373,7 +373,7 @@ pub async fn routing_unlink_config(
         },
         #[cfg(not(feature = "release"))]
         auth::auth_type(
-            &auth::ApiKeyAuth,
+            &auth::V2ApiKeyAuth,
             &auth::JWTAuthProfileFromRoute {
                 profile_id: path,
                 required_permission: Permission::MerchantRoutingWrite,
@@ -459,7 +459,7 @@ pub async fn routing_update_default_config(
         },
         #[cfg(not(feature = "release"))]
         auth::auth_type(
-            &auth::HeaderAuth(auth::ApiKeyAuth),
+            &auth::V2ApiKeyAuth,
             &auth::JWTAuth {
                 permission: Permission::MerchantRoutingWrite,
             },
@@ -535,7 +535,7 @@ pub async fn routing_retrieve_default_config(
         },
         #[cfg(not(feature = "release"))]
         auth::auth_type(
-            &auth::HeaderAuth(auth::ApiKeyAuth),
+            &auth::V2ApiKeyAuth,
             &auth::JWTAuthProfileFromRoute {
                 profile_id: path,
                 required_permission: Permission::MerchantRoutingRead,
@@ -749,7 +749,7 @@ pub async fn upsert_decision_manager_config(
         },
         #[cfg(not(feature = "release"))]
         auth::auth_type(
-            &auth::HeaderAuth(auth::ApiKeyAuth),
+            &auth::V2ApiKeyAuth,
             &auth::JWTAuth {
                 permission: Permission::ProfileThreeDsDecisionManagerWrite,
             },
@@ -818,7 +818,7 @@ pub async fn retrieve_decision_manager_config(
         },
         #[cfg(not(feature = "release"))]
         auth::auth_type(
-            &auth::HeaderAuth(auth::ApiKeyAuth),
+            &auth::V2ApiKeyAuth,
             &auth::JWTAuth {
                 permission: Permission::ProfileThreeDsDecisionManagerWrite,
             },
@@ -976,7 +976,7 @@ pub async fn routing_retrieve_linked_config(
         },
         #[cfg(not(feature = "release"))]
         auth::auth_type(
-            &auth::HeaderAuth(auth::ApiKeyAuth),
+            &auth::V2ApiKeyAuth,
             &auth::JWTAuthProfileFromRoute {
                 profile_id: wrapper.profile_id,
                 required_permission: Permission::ProfileRoutingRead,
diff --git a/crates/router/src/services/authentication.rs b/crates/router/src/services/authentication.rs
index 502ebb5099f..4eb91756661 100644
--- a/crates/router/src/services/authentication.rs
+++ b/crates/router/src/services/authentication.rs
@@ -1064,6 +1064,44 @@ where
     }
 }
 
+#[derive(Debug, Default)]
+pub struct V2AdminApiAuth;
+
+#[async_trait]
+impl<A> AuthenticateAndFetch<(), A> for V2AdminApiAuth
+where
+    A: SessionStateInfo + Sync,
+{
+    async fn authenticate_and_fetch(
+        &self,
+        request_headers: &HeaderMap,
+        state: &A,
+    ) -> RouterResult<((), AuthenticationType)> {
+        let header_map_struct = HeaderMapStruct::new(request_headers);
+        let auth_string = header_map_struct.get_auth_string_from_header()?;
+        let request_admin_api_key = auth_string
+            .split(',')
+            .find_map(|part| part.trim().strip_prefix("admin-api-key="))
+            .ok_or_else(|| {
+                report!(errors::ApiErrorResponse::Unauthorized)
+                    .attach_printable("Unable to parse admin_api_key")
+            })?;
+        if request_admin_api_key.is_empty() {
+            return Err(errors::ApiErrorResponse::Unauthorized)
+                .attach_printable("Admin Api key is empty");
+        }
+        let conf = state.conf();
+
+        let admin_api_key = &conf.secrets.get_inner().admin_api_key;
+
+        if request_admin_api_key != admin_api_key.peek() {
+            Err(report!(errors::ApiErrorResponse::Unauthorized)
+                .attach_printable("Admin Authentication Failure"))?;
+        }
+
+        Ok(((), AuthenticationType::AdminApiKey))
+    }
+}
 #[derive(Debug)]
 pub struct AdminApiAuthWithMerchantIdFromRoute(pub id_type::MerchantId);
 
@@ -1130,7 +1168,7 @@ where
             throw_error_if_platform_merchant_authentication_required(request_headers)?;
         }
 
-        AdminApiAuth
+        V2AdminApiAuth
             .authenticate_and_fetch(request_headers, state)
             .await?;
 
@@ -1194,7 +1232,7 @@ where
             throw_error_if_platform_merchant_authentication_required(request_headers)?;
         }
 
-        AdminApiAuth
+        V2AdminApiAuth
             .authenticate_and_fetch(request_headers, state)
             .await?;
 
@@ -1400,7 +1438,7 @@ where
             throw_error_if_platform_merchant_authentication_required(request_headers)?;
         }
 
-        AdminApiAuth
+        V2AdminApiAuth
             .authenticate_and_fetch(request_headers, state)
             .await?;
 
@@ -1465,7 +1503,7 @@ where
             throw_error_if_platform_merchant_authentication_required(request_headers)?;
         }
 
-        AdminApiAuth
+        V2AdminApiAuth
             .authenticate_and_fetch(request_headers, state)
             .await?;
 

## Type of Change

- [ ] Bugfix
- [ ] New feature
- [x] Enhancement
- [ ] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD

## Description

This commit introduces V2 authentication mechanisms for various admin and client-side APIs :
- [x] Added V2AdminApiAuth and modified AdminApiAuthWithMerchantIdFromRoute for V2
- [x] Added V2ApiKeyAuth , V2AdminApiAuth and V2ClientAuth to the endpoints
- [x] Refactored functions to support V2 Auth as well as V1 Auth

### Additional Changes

- [ ] This PR modifies the API contract
- [ ] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables

## Motivation and Context

## How did you test it?

For   `/v2/merchant-accounts`


Request 
```
curl --location 'http://localhost:8080/v2/merchant-accounts' \
--header 'x-organization-id: org_d2lZPiRPOGbIMmFcb59A' \
--header 'Content-Type: application/json' \
--header 'Authorization: admin-api-key=test_admin' \
--data '{
    "merchant_name": "cloth_seller"
}'
```
Response

```
{
    "id": "cloth_seller_KdjFPBxrxWyX09jri2VB",
    "merchant_name": "cloth_seller",
    "merchant_details": null,
    "publishable_key": "pk_dev_735cafe5f43446e88d22bedec15b0139",
    "metadata": null,
    "organization_id": "org_d2lZPiRPOGbIMmFcb59A",
    "recon_status": "not_requested",
    "product_type": "orchestration"
}
```

For `/v2/organization`

Request

```
curl --location 'http://localhost:8080/v2/organization' \
--header 'Authorization: admin-api-key=test_admin' \
--header 'Content-Type: application/json' \
--data '{
    "organization_name": "random_org_1741776562"
}'
```
Response

```
{
    "id": "org_m4fLYdEFb7PNHynIfmZO",
    "organization_name": "random_org_1741776558",
    "organization_details": null,
    "metadata": null,
    "modified_at": "2025-03-12 10:49:18.475431",
    "created_at": "2025-03-12 10:49:18.475424"
}
```

This is how V2AdminApiAuth looks like 

```
pub struct V2AdminApiAuth;

#[async_trait]
impl<A> AuthenticateAndFetch<(), A> for V2AdminApiAuth
where
    A: SessionStateInfo + Sync,
{
    async fn authenticate_and_fetch(
        &self,
        request_headers: &HeaderMap,
        state: &A,
    ) -> RouterResult<((), AuthenticationType)> {
        let header_map_struct = HeaderMapStruct::new(&request_headers);
        let auth_string = header_map_struct.get_auth_string_from_header()?;
        let request_admin_api_key = auth_string
            .split(',')
            .find_map(|part| part.trim().strip_prefix("admin-api-key="))
            .ok_or_else(|| {
                report!(errors::ApiErrorResponse::Unauthorized)
                    .attach_printable("Unable to parse admin_api_key")
            })?;
        if request_admin_api_key.is_empty() {
            return Err(errors::ApiErrorResponse::Unauthorized)
                .attach_printable("Admin Api key is empty");
        }
        let conf = state.conf();

        let admin_api_key = &conf.secrets.get_inner().admin_api_key;

        if request_admin_api_key != admin_api_key.peek() {
            Err(report!(errors::ApiErrorResponse::Unauthorized)
                .attach_printable("Admin Authentication Failure"))?;
        }

        Ok(((), AuthenticationType::AdminApiKey))
    }
}
```
### What changes are done in authorization header

How it was earlier?

```
api-key = {{api-key}}
client-secret={{client_secret}} 
api-key = {{admin_api_key}}
```

Changed version

```
Authorization = api-key={{api-key}} 
Authorization = admin-api-key={{admin_api_key}}
Authorization = publishable-key={{publishable_key}},client-secret={{client_secret}} 
```


## Checklist
<!-- Put an `x` in the boxes that apply -->

- [ ] I formatted the code `cargo +nightly fmt --all`
- [x] I addressed lints thrown by `cargo clippy`
- [x] I reviewed the submitted code
- [ ] I added unit tests for my changes where possible