diff --git a/api-reference-v2/openapi_spec.json b/api-reference-v2/openapi_spec.json index f7aa7923b0..94cffcd75a 100644 --- a/api-reference-v2/openapi_spec.json +++ b/api-reference-v2/openapi_spec.json @@ -164,6 +164,50 @@ ] } }, + "/v2/organization/{organization_id}/merchant_accounts": { + "get": { + "tags": [ + "Organization" + ], + "summary": "Merchant Account - List", + "description": "List merchant accounts for an Organization", + "operationId": "List Merchant Accounts", + "parameters": [ + { + "name": "organization_id", + "in": "path", + "description": "The unique identifier for the Organization", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Merchant Account list retrieved successfully", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/MerchantAccountResponse" + } + } + } + } + }, + "400": { + "description": "Invalid data" + } + }, + "security": [ + { + "admin_api_key": [] + } + ] + } + }, "/v2/connector_accounts": { "post": { "tags": [ @@ -401,7 +445,7 @@ ] } }, - "/v2/accounts": { + "/v2/merchant_accounts": { "post": { "tags": [ "Merchant Account" @@ -469,7 +513,7 @@ ] } }, - "/v2/accounts/{id}": { + "/v2/merchant_accounts/{id}": { "get": { "tags": [ "Merchant Account" @@ -575,6 +619,50 @@ ] } }, + "/v2/merchant_accounts/{account_id}/profiles": { + "get": { + "tags": [ + "Merchant Account" + ], + "summary": "Business Profile - List", + "description": "List business profiles for an Merchant", + "operationId": "List Business Profiles", + "parameters": [ + { + "name": "account_id", + "in": "path", + "description": "The unique identifier for the Merchant", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Business profile list retrieved successfully", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BusinessProfileResponse" + } + } + } + } + }, + "400": { + "description": "Invalid data" + } + }, + "security": [ + { + "admin_api_key": [] + } + ] + } + }, "/v2/profiles": { "post": { "tags": [ @@ -719,6 +807,53 @@ ] } }, + "/v2/profiles/{profile_id}/connector_accounts": { + "get": { + "tags": [ + "Business Profile" + ], + "summary": "Merchant Connector - List", + "description": "List Merchant Connector Details for the business profile", + "operationId": "List all Merchant Connectors", + "parameters": [ + { + "name": "profile_id", + "in": "path", + "description": "The unique identifier for the business profile", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Merchant Connector list retrieved successfully", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/MerchantConnectorResponse" + } + } + } + } + }, + "401": { + "description": "Unauthorized request" + }, + "404": { + "description": "Merchant Connector does not exist in records" + } + }, + "security": [ + { + "admin_api_key": [] + } + ] + } + }, "/v2/profiles/{profile_id}/activate_routing_algorithm": { "patch": { "tags": [ diff --git a/crates/api_models/src/admin.rs b/crates/api_models/src/admin.rs index ef00c22433..1846ef0e45 100644 --- a/crates/api_models/src/admin.rs +++ b/crates/api_models/src/admin.rs @@ -26,7 +26,7 @@ use crate::{ #[derive(Clone, Debug, Deserialize, ToSchema, Serialize)] pub struct MerchantAccountListRequest { - pub organization_id: String, + pub organization_id: id_type::OrganizationId, } #[cfg(feature = "v1")] diff --git a/crates/diesel_models/src/query/merchant_account.rs b/crates/diesel_models/src/query/merchant_account.rs index e6aa5c25c2..fd5a171b7e 100644 --- a/crates/diesel_models/src/query/merchant_account.rs +++ b/crates/diesel_models/src/query/merchant_account.rs @@ -91,7 +91,7 @@ impl MerchantAccount { pub async fn list_by_organization_id( conn: &PgPooledConn, - organization_id: &str, + organization_id: &common_utils::id_type::OrganizationId, ) -> StorageResult> { generics::generic_filter::< ::Table, diff --git a/crates/diesel_models/src/query/merchant_connector_account.rs b/crates/diesel_models/src/query/merchant_connector_account.rs index 0ebf0ab9c0..0f09544200 100644 --- a/crates/diesel_models/src/query/merchant_connector_account.rs +++ b/crates/diesel_models/src/query/merchant_connector_account.rs @@ -227,4 +227,18 @@ impl MerchantConnectorAccount { .await } } + + pub async fn list_by_profile_id( + conn: &PgPooledConn, + profile_id: &common_utils::id_type::ProfileId, + ) -> StorageResult> { + generics::generic_filter::<::Table, _, _, _>( + conn, + dsl::profile_id.eq(profile_id.to_owned()), + None, + None, + Some(dsl::created_at.asc()), + ) + .await + } } diff --git a/crates/openapi/src/openapi.rs b/crates/openapi/src/openapi.rs index 297228cc25..d71757e8f3 100644 --- a/crates/openapi/src/openapi.rs +++ b/crates/openapi/src/openapi.rs @@ -104,7 +104,7 @@ Never share your secret api keys. Keep them guarded and secure. // Routes for merchant connector account routes::merchant_connector_account::connector_create, routes::merchant_connector_account::connector_retrieve, - routes::merchant_connector_account::payment_connector_list, + routes::merchant_connector_account::connector_list, routes::merchant_connector_account::connector_update, routes::merchant_connector_account::connector_delete, diff --git a/crates/openapi/src/openapi_v2.rs b/crates/openapi/src/openapi_v2.rs index 31feb8e85b..f2a920cdb9 100644 --- a/crates/openapi/src/openapi_v2.rs +++ b/crates/openapi/src/openapi_v2.rs @@ -73,6 +73,7 @@ Never share your secret api keys. Keep them guarded and secure. routes::organization::organization_create, routes::organization::organization_retrieve, routes::organization::organization_update, + routes::organization::merchant_account_list, // Routes for merchant connector account routes::merchant_connector_account::connector_create, @@ -84,11 +85,13 @@ Never share your secret api keys. Keep them guarded and secure. routes::merchant_account::merchant_account_create, routes::merchant_account::merchant_account_retrieve, routes::merchant_account::merchant_account_update, + routes::merchant_account::business_profiles_list, // Routes for business profile routes::business_profile::business_profile_create, routes::business_profile::business_profile_retrieve, routes::business_profile::business_profile_update, + routes::business_profile::connector_list, // Routes for routing under business profile routes::business_profile::routing_link_config, diff --git a/crates/openapi/src/routes/business_profile.rs b/crates/openapi/src/routes/business_profile.rs index 07442f9757..89003da08e 100644 --- a/crates/openapi/src/routes/business_profile.rs +++ b/crates/openapi/src/routes/business_profile.rs @@ -323,3 +323,24 @@ pub async fn routing_update_default_config() {} security(("api_key" = []), ("jwt_key" = [])) )] pub async fn routing_retrieve_default_config() {} + +/// Merchant Connector - List +/// +/// List Merchant Connector Details for the business profile +#[utoipa::path( + get, + path = "/v2/profiles/{profile_id}/connector_accounts", + params( + ("profile_id" = String, Path, description = "The unique identifier for the business profile"), + ), + responses( + (status = 200, description = "Merchant Connector list retrieved successfully", body = Vec), + (status = 404, description = "Merchant Connector does not exist in records"), + (status = 401, description = "Unauthorized request") + ), + tag = "Business Profile", + operation_id = "List all Merchant Connectors", + security(("admin_api_key" = [])) +)] +#[cfg(feature = "v2")] +pub async fn connector_list() {} diff --git a/crates/openapi/src/routes/merchant_account.rs b/crates/openapi/src/routes/merchant_account.rs index 7e5106d132..16533c6a61 100644 --- a/crates/openapi/src/routes/merchant_account.rs +++ b/crates/openapi/src/routes/merchant_account.rs @@ -50,7 +50,7 @@ pub async fn merchant_account_create() {} /// Before creating the merchant account, it is mandatory to create an organization. #[utoipa::path( post, - path = "/v2/accounts", + path = "/v2/merchant_accounts", request_body( content = MerchantAccountCreate, examples( @@ -124,7 +124,7 @@ pub async fn retrieve_merchant_account() {} /// Retrieve a *merchant* account details. #[utoipa::path( get, - path = "/v2/accounts/{id}", + path = "/v2/merchant_accounts/{id}", params (("id" = String, Path, description = "The unique identifier for the merchant account")), responses( (status = 200, description = "Merchant Account Retrieved", body = MerchantAccountResponse), @@ -186,7 +186,7 @@ pub async fn update_merchant_account() {} /// Updates details of an existing merchant account. Helpful in updating merchant details such as email, contact details, or other configuration details like webhook, routing algorithm etc #[utoipa::path( put, - path = "/v2/accounts/{id}", + path = "/v2/merchant_accounts/{id}", request_body ( content = MerchantAccountUpdate, examples( @@ -269,3 +269,21 @@ pub async fn delete_merchant_account() {} security(("admin_api_key" = [])) )] pub async fn merchant_account_kv_status() {} + +#[cfg(feature = "v2")] +/// Business Profile - List +/// +/// List business profiles for an Merchant +#[utoipa::path( + get, + path = "/v2/merchant_accounts/{account_id}/profiles", + params (("account_id" = String, Path, description = "The unique identifier for the Merchant")), + responses( + (status = 200, description = "Business profile list retrieved successfully", body = Vec), + (status = 400, description = "Invalid data") + ), + tag = "Merchant Account", + operation_id = "List Business Profiles", + security(("admin_api_key" = [])) +)] +pub async fn business_profiles_list() {} diff --git a/crates/openapi/src/routes/merchant_connector_account.rs b/crates/openapi/src/routes/merchant_connector_account.rs index 55c6d88aac..a7c91ce128 100644 --- a/crates/openapi/src/routes/merchant_connector_account.rs +++ b/crates/openapi/src/routes/merchant_connector_account.rs @@ -185,7 +185,7 @@ pub async fn connector_retrieve() {} operation_id = "List all Merchant Connectors", security(("admin_api_key" = [])) )] -pub async fn payment_connector_list() {} +pub async fn connector_list() {} /// Merchant Connector - Update /// diff --git a/crates/openapi/src/routes/organization.rs b/crates/openapi/src/routes/organization.rs index c31ff70a79..44d5f94357 100644 --- a/crates/openapi/src/routes/organization.rs +++ b/crates/openapi/src/routes/organization.rs @@ -143,3 +143,21 @@ pub async fn organization_retrieve() {} security(("admin_api_key" = [])) )] pub async fn organization_update() {} + +#[cfg(feature = "v2")] +/// Merchant Account - List +/// +/// List merchant accounts for an Organization +#[utoipa::path( + get, + path = "/v2/organization/{organization_id}/merchant_accounts", + params (("organization_id" = String, Path, description = "The unique identifier for the Organization")), + responses( + (status = 200, description = "Merchant Account list retrieved successfully", body = Vec), + (status = 400, description = "Invalid data") + ), + tag = "Organization", + operation_id = "List Merchant Accounts", + security(("admin_api_key" = [])) +)] +pub async fn merchant_account_list() {} diff --git a/crates/router/src/core/admin.rs b/crates/router/src/core/admin.rs index 8ed2eb48b1..690d16596b 100644 --- a/crates/router/src/core/admin.rs +++ b/crates/router/src/core/admin.rs @@ -674,7 +674,35 @@ impl MerchantAccountCreateBridge for api::MerchantAccountCreate { } } -#[cfg(feature = "olap")] +#[cfg(all(feature = "olap", feature = "v2"))] +pub async fn list_merchant_account( + state: SessionState, + organization_id: api_models::organization::OrganizationId, +) -> RouterResponse> { + let merchant_accounts = state + .store + .list_merchant_accounts_by_organization_id( + &(&state).into(), + &organization_id.organization_id, + ) + .await + .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?; + + let merchant_accounts = merchant_accounts + .into_iter() + .map(|merchant_account| { + api::MerchantAccountResponse::foreign_try_from(merchant_account).change_context( + errors::ApiErrorResponse::InvalidDataValue { + field_name: "merchant_account", + }, + ) + }) + .collect::, _>>()?; + + Ok(services::ApplicationResponse::Json(merchant_accounts)) +} + +#[cfg(all(feature = "olap", feature = "v1"))] pub async fn list_merchant_account( state: SessionState, req: api_models::admin::MerchantAccountListRequest, @@ -2920,6 +2948,36 @@ pub async fn retrieve_connector( )) } +#[cfg(all(feature = "olap", feature = "v2"))] +pub async fn list_connectors_for_a_profile( + state: SessionState, + merchant_account: domain::MerchantAccount, + profile_id: id_type::ProfileId, +) -> RouterResponse> { + let store = state.store.as_ref(); + let key_manager_state = &(&state).into(); + let key_store = store + .get_merchant_key_store_by_merchant_id( + key_manager_state, + merchant_account.get_id(), + &store.get_master_key().to_vec().into(), + ) + .await + .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?; + + let merchant_connector_accounts = store + .list_connector_account_by_profile_id(key_manager_state, &profile_id, &key_store) + .await + .to_not_found_response(errors::ApiErrorResponse::InternalServerError)?; + let mut response = vec![]; + + for mca in merchant_connector_accounts.into_iter() { + response.push(mca.foreign_try_into()?); + } + + Ok(service_api::ApplicationResponse::Json(response)) +} + pub async fn list_payment_connectors( state: SessionState, merchant_id: id_type::MerchantId, diff --git a/crates/router/src/core/user.rs b/crates/router/src/core/user.rs index 45e9065d26..9d0f168827 100644 --- a/crates/router/src/core/user.rs +++ b/crates/router/src/core/user.rs @@ -2681,10 +2681,7 @@ pub async fn list_merchants_for_user_in_org( let merchant_accounts = match role_info.get_entity_type() { EntityType::Organization | EntityType::Internal => state .store - .list_merchant_accounts_by_organization_id( - &(&state).into(), - user_from_token.org_id.get_string_repr(), - ) + .list_merchant_accounts_by_organization_id(&(&state).into(), &user_from_token.org_id) .await .change_context(UserErrors::InternalServerError)?, EntityType::Merchant | EntityType::Profile => { diff --git a/crates/router/src/db/kafka_store.rs b/crates/router/src/db/kafka_store.rs index 6c620c4fcd..4892e2552e 100644 --- a/crates/router/src/db/kafka_store.rs +++ b/crates/router/src/db/kafka_store.rs @@ -1008,7 +1008,7 @@ impl MerchantAccountInterface for KafkaStore { async fn list_merchant_accounts_by_organization_id( &self, state: &KeyManagerState, - organization_id: &str, + organization_id: &id_type::OrganizationId, ) -> CustomResult, errors::StorageError> { self.diesel_store .list_merchant_accounts_by_organization_id(state, organization_id) @@ -1225,6 +1225,18 @@ impl MerchantConnectorAccountInterface for KafkaStore { .await } + #[cfg(all(feature = "olap", feature = "v2"))] + async fn list_connector_account_by_profile_id( + &self, + state: &KeyManagerState, + profile_id: &id_type::ProfileId, + key_store: &domain::MerchantKeyStore, + ) -> CustomResult, errors::StorageError> { + self.diesel_store + .list_connector_account_by_profile_id(state, profile_id, key_store) + .await + } + async fn update_merchant_connector_account( &self, state: &KeyManagerState, diff --git a/crates/router/src/db/merchant_account.rs b/crates/router/src/db/merchant_account.rs index c3b2c45f33..13a778001a 100644 --- a/crates/router/src/db/merchant_account.rs +++ b/crates/router/src/db/merchant_account.rs @@ -74,7 +74,7 @@ where async fn list_merchant_accounts_by_organization_id( &self, state: &KeyManagerState, - organization_id: &str, + organization_id: &common_utils::id_type::OrganizationId, ) -> CustomResult, errors::StorageError>; async fn delete_merchant_account_by_merchant_id( @@ -282,7 +282,7 @@ impl MerchantAccountInterface for Store { async fn list_merchant_accounts_by_organization_id( &self, state: &KeyManagerState, - organization_id: &str, + organization_id: &common_utils::id_type::OrganizationId, ) -> CustomResult, errors::StorageError> { use futures::future::try_join_all; let conn = connection::pg_connection_read(self).await?; @@ -555,7 +555,7 @@ impl MerchantAccountInterface for MockDb { async fn list_merchant_accounts_by_organization_id( &self, _state: &KeyManagerState, - _organization_id: &str, + _organization_id: &common_utils::id_type::OrganizationId, ) -> CustomResult, errors::StorageError> { Err(errors::StorageError::MockDbError)? } diff --git a/crates/router/src/db/merchant_connector_account.rs b/crates/router/src/db/merchant_connector_account.rs index c13fd3fe9b..40e5357249 100644 --- a/crates/router/src/db/merchant_connector_account.rs +++ b/crates/router/src/db/merchant_connector_account.rs @@ -181,6 +181,14 @@ where key_store: &domain::MerchantKeyStore, ) -> CustomResult, errors::StorageError>; + #[cfg(all(feature = "olap", feature = "v2"))] + async fn list_connector_account_by_profile_id( + &self, + state: &KeyManagerState, + profile_id: &common_utils::id_type::ProfileId, + key_store: &domain::MerchantKeyStore, + ) -> CustomResult, errors::StorageError>; + async fn update_merchant_connector_account( &self, state: &KeyManagerState, @@ -515,6 +523,36 @@ impl MerchantConnectorAccountInterface for Store { .await } + #[instrument(skip_all)] + #[cfg(all(feature = "olap", feature = "v2"))] + async fn list_connector_account_by_profile_id( + &self, + state: &KeyManagerState, + profile_id: &common_utils::id_type::ProfileId, + key_store: &domain::MerchantKeyStore, + ) -> CustomResult, errors::StorageError> { + let conn = connection::pg_connection_read(self).await?; + storage::MerchantConnectorAccount::list_by_profile_id(&conn, profile_id) + .await + .map_err(|error| report!(errors::StorageError::from(error))) + .async_and_then(|items| async { + let mut output = Vec::with_capacity(items.len()); + for item in items.into_iter() { + output.push( + item.convert( + state, + key_store.key.get_inner(), + key_store.merchant_id.clone().into(), + ) + .await + .change_context(errors::StorageError::DecryptionError)?, + ) + } + Ok(output) + }) + .await + } + #[instrument(skip_all)] async fn update_multiple_merchant_connector_accounts( &self, @@ -1252,6 +1290,40 @@ impl MerchantConnectorAccountInterface for MockDb { Ok(output) } + #[cfg(all(feature = "olap", feature = "v2"))] + async fn list_connector_account_by_profile_id( + &self, + state: &KeyManagerState, + profile_id: &common_utils::id_type::ProfileId, + key_store: &domain::MerchantKeyStore, + ) -> CustomResult, errors::StorageError> { + let accounts = self + .merchant_connector_accounts + .lock() + .await + .iter() + .filter(|account: &&storage::MerchantConnectorAccount| { + account.profile_id == *profile_id + }) + .cloned() + .collect::>(); + + let mut output = Vec::with_capacity(accounts.len()); + for account in accounts.into_iter() { + output.push( + account + .convert( + state, + key_store.key.get_inner(), + key_store.merchant_id.clone().into(), + ) + .await + .change_context(errors::StorageError::DecryptionError)?, + ) + } + Ok(output) + } + #[cfg(feature = "v1")] async fn update_merchant_connector_account( &self, diff --git a/crates/router/src/routes/admin.rs b/crates/router/src/routes/admin.rs index 0dc34aa424..a68f648e17 100644 --- a/crates/router/src/routes/admin.rs +++ b/crates/router/src/routes/admin.rs @@ -128,7 +128,39 @@ pub async fn retrieve_merchant_account( .await } -#[cfg(feature = "olap")] +#[cfg(all(feature = "olap", feature = "v2"))] +#[instrument(skip_all, fields(flow = ?Flow::MerchantAccountList))] +pub async fn merchant_account_list( + state: web::Data, + req: HttpRequest, + organization_id: web::Path, +) -> HttpResponse { + let flow = Flow::MerchantAccountList; + + let organization_id = admin::OrganizationId { + organization_id: organization_id.into_inner(), + }; + + Box::pin(api::server_wrap( + flow, + state, + &req, + organization_id, + |state, _, request, _| list_merchant_account(state, request), + auth::auth_type( + &auth::AdminApiAuth, + &auth::JWTAuthMerchantFromHeader { + required_permission: Permission::MerchantAccountRead, + minimum_entity_level: EntityType::Merchant, + }, + req.headers(), + ), + api_locking::LockAction::NotApplicable, + )) + .await +} + +#[cfg(all(feature = "olap", feature = "v1"))] #[instrument(skip_all, fields(flow = ?Flow::MerchantAccountList))] pub async fn merchant_account_list( state: web::Data, @@ -143,7 +175,14 @@ pub async fn merchant_account_list( &req, query_params.into_inner(), |state, _, request, _| list_merchant_account(state, request), - &auth::AdminApiAuth, + auth::auth_type( + &auth::AdminApiAuth, + &auth::JWTAuthMerchantFromHeader { + required_permission: Permission::MerchantAccountRead, + minimum_entity_level: EntityType::Merchant, + }, + req.headers(), + ), api_locking::LockAction::NotApplicable, )) .await @@ -387,6 +426,38 @@ pub async fn connector_retrieve( ) .await } + +#[cfg(all(feature = "olap", feature = "v2"))] +#[instrument(skip_all, fields(flow = ?Flow::MerchantConnectorsList))] +pub async fn connector_list( + state: web::Data, + req: HttpRequest, + path: web::Path, +) -> HttpResponse { + let flow = Flow::MerchantConnectorsList; + let profile_id = path.into_inner(); + + api::server_wrap( + flow, + state, + &req, + profile_id.to_owned(), + |state, auth, _, _| { + list_connectors_for_a_profile(state, auth.merchant_account.clone(), profile_id.clone()) + }, + auth::auth_type( + &auth::AdminApiAuthWithMerchantIdFromHeader, + &auth::JWTAuthMerchantFromHeader { + required_permission: Permission::MerchantConnectorAccountRead, + minimum_entity_level: EntityType::Merchant, + }, + req.headers(), + ), + api_locking::LockAction::NotApplicable, + ) + .await +} + /// Merchant Connector - List /// /// List Merchant Connector Details for the merchant @@ -405,8 +476,9 @@ pub async fn connector_retrieve( operation_id = "List all Merchant Connectors", security(("admin_api_key" = [])) )] +#[cfg(feature = "v1")] #[instrument(skip_all, fields(flow = ?Flow::MerchantConnectorsList))] -pub async fn payment_connector_list( +pub async fn connector_list( state: web::Data, req: HttpRequest, path: web::Path, @@ -452,7 +524,7 @@ pub async fn payment_connector_list( security(("admin_api_key" = [])) )] #[instrument(skip_all, fields(flow = ?Flow::MerchantConnectorsList))] -pub async fn payment_connector_list_profile( +pub async fn connector_list_profile( state: web::Data, req: HttpRequest, path: web::Path, diff --git a/crates/router/src/routes/app.rs b/crates/router/src/routes/app.rs index da1a50b82e..d66dc8e51e 100644 --- a/crates/router/src/routes/app.rs +++ b/crates/router/src/routes/app.rs @@ -1190,9 +1190,16 @@ impl Organization { .app_data(web::Data::new(state)) .service(web::resource("").route(web::post().to(admin::organization_create))) .service( - web::resource("/{id}") - .route(web::get().to(admin::organization_retrieve)) - .route(web::put().to(admin::organization_update)), + web::scope("/{id}") + .service( + web::resource("") + .route(web::get().to(admin::organization_retrieve)) + .route(web::put().to(admin::organization_update)), + ) + .service( + web::resource("/merchant_accounts") + .route(web::get().to(admin::merchant_account_list)), + ), ) } } @@ -1202,13 +1209,20 @@ pub struct MerchantAccount; #[cfg(all(feature = "v2", feature = "olap"))] impl MerchantAccount { pub fn server(state: AppState) -> Scope { - web::scope("/v2/accounts") + web::scope("/v2/merchant_accounts") .app_data(web::Data::new(state)) .service(web::resource("").route(web::post().to(admin::merchant_account_create))) .service( - web::resource("/{id}") - .route(web::get().to(admin::retrieve_merchant_account)) - .route(web::put().to(admin::update_merchant_account)), + web::scope("/{id}") + .service( + web::resource("") + .route(web::get().to(admin::retrieve_merchant_account)) + .route(web::put().to(admin::update_merchant_account)), + ) + .service( + web::resource("/profiles") + .route(web::get().to(admin::business_profiles_list)), + ), ) } } @@ -1282,7 +1296,7 @@ impl MerchantConnectorAccount { .service( web::resource("/{merchant_id}/connectors") .route(web::post().to(connector_create)) - .route(web::get().to(payment_connector_list)), + .route(web::get().to(connector_list)), ) .service( web::resource("/{merchant_id}/connectors/{merchant_connector_id}") @@ -1570,6 +1584,10 @@ impl BusinessProfile { .route(web::get().to(super::admin::business_profile_retrieve)) .route(web::put().to(super::admin::business_profile_update)), ) + .service( + web::resource("/connector_accounts") + .route(web::get().to(admin::connector_list)), + ) .service( web::resource("/fallback_routing") .route(web::get().to(routing::routing_retrieve_default_config)) @@ -1673,8 +1691,7 @@ impl BusinessProfileNew { .route(web::get().to(admin::business_profiles_list_at_profile_level)), ) .service( - web::resource("/connectors") - .route(web::get().to(admin::payment_connector_list_profile)), + web::resource("/connectors").route(web::get().to(admin::connector_list_profile)), ) } } diff --git a/crates/router/src/utils/user_role.rs b/crates/router/src/utils/user_role.rs index 2d700ffe50..3936ff60b7 100644 --- a/crates/router/src/utils/user_role.rs +++ b/crates/router/src/utils/user_role.rs @@ -229,8 +229,7 @@ pub async fn get_single_merchant_id( .org_id .as_ref() .ok_or(UserErrors::InternalServerError) - .attach_printable("org_id not found")? - .get_string_repr(), + .attach_printable("org_id not found")?, ) .await .change_context(UserErrors::InternalServerError) diff --git a/v2_migrations/2024-09-13-075054_create-index-profile-id-mca/down.sql b/v2_migrations/2024-09-13-075054_create-index-profile-id-mca/down.sql new file mode 100644 index 0000000000..32225e3496 --- /dev/null +++ b/v2_migrations/2024-09-13-075054_create-index-profile-id-mca/down.sql @@ -0,0 +1,2 @@ +-- This file should undo anything in `up.sql` +DROP INDEX IF EXISTS merchant_connector_account_profile_id_index; \ No newline at end of file diff --git a/v2_migrations/2024-09-13-075054_create-index-profile-id-mca/up.sql b/v2_migrations/2024-09-13-075054_create-index-profile-id-mca/up.sql new file mode 100644 index 0000000000..f4ca993fef --- /dev/null +++ b/v2_migrations/2024-09-13-075054_create-index-profile-id-mca/up.sql @@ -0,0 +1,2 @@ +-- Your SQL goes here +CREATE INDEX IF NOT EXISTS merchant_connector_account_profile_id_index ON merchant_connector_account (profile_id);