mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-11-01 02:57:02 +08:00 
			
		
		
		
	refactor(router): refactor merchant_connector_account retrieve and delete v2 apis (#5528)
				
					
				
			This commit is contained in:
		 Sai Harsha Vardhan
					Sai Harsha Vardhan
				
			
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			 GitHub
						GitHub
					
				
			
						parent
						
							7e545e36eb
						
					
				
				
					commit
					253f1be3e1
				
			| @ -663,12 +663,21 @@ pub struct MerchantId { | |||||||
|     pub merchant_id: id_type::MerchantId, |     pub merchant_id: id_type::MerchantId, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[cfg(all( | ||||||
|  |     any(feature = "v1", feature = "v2"), | ||||||
|  |     not(feature = "merchant_connector_account_v2") | ||||||
|  | ))] | ||||||
| #[derive(Default, Debug, Deserialize, ToSchema, Serialize)] | #[derive(Default, Debug, Deserialize, ToSchema, Serialize)] | ||||||
| pub struct MerchantConnectorId { | pub struct MerchantConnectorId { | ||||||
|     #[schema(value_type = String)] |     #[schema(value_type = String)] | ||||||
|     pub merchant_id: id_type::MerchantId, |     pub merchant_id: id_type::MerchantId, | ||||||
|     pub merchant_connector_id: String, |     pub merchant_connector_id: String, | ||||||
| } | } | ||||||
|  | #[cfg(all(feature = "v2", feature = "merchant_connector_account_v2"))] | ||||||
|  | #[derive(Default, Debug, Deserialize, ToSchema, Serialize)] | ||||||
|  | pub struct MerchantConnectorId { | ||||||
|  |     pub id: String, | ||||||
|  | } | ||||||
|  |  | ||||||
| #[cfg(all(feature = "v2", feature = "merchant_connector_account_v2"))] | #[cfg(all(feature = "v2", feature = "merchant_connector_account_v2"))] | ||||||
| /// Create a new Merchant Connector for the merchant account. The connector could be a payment processor / facilitator / acquirer or specialized services like Fraud / Accounting etc." | /// Create a new Merchant Connector for the merchant account. The connector could be a payment processor / facilitator / acquirer or specialized services like Fraud / Accounting etc." | ||||||
| @ -1728,6 +1737,10 @@ pub enum AcceptedCountries { | |||||||
|     AllAccepted, |     AllAccepted, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[cfg(all( | ||||||
|  |     any(feature = "v1", feature = "v2"), | ||||||
|  |     not(feature = "merchant_connector_account_v2") | ||||||
|  | ))] | ||||||
| #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] | #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] | ||||||
| pub struct MerchantConnectorDeleteResponse { | pub struct MerchantConnectorDeleteResponse { | ||||||
|     /// The identifier for the Merchant Account |     /// The identifier for the Merchant Account | ||||||
| @ -1741,6 +1754,20 @@ pub struct MerchantConnectorDeleteResponse { | |||||||
|     pub deleted: bool, |     pub deleted: bool, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[cfg(all(feature = "v2", feature = "merchant_connector_account_v2"))] | ||||||
|  | #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] | ||||||
|  | pub struct MerchantConnectorDeleteResponse { | ||||||
|  |     /// The identifier for the Merchant Account | ||||||
|  |     #[schema(max_length = 255, example = "y3oqhf46pyzuxjbcn2giaqnb44", value_type = String)] | ||||||
|  |     pub merchant_id: id_type::MerchantId, | ||||||
|  |     /// Unique ID of the connector | ||||||
|  |     #[schema(example = "mca_5apGeP94tMts6rg3U3kR")] | ||||||
|  |     pub id: String, | ||||||
|  |     /// If the connector is deleted or not | ||||||
|  |     #[schema(example = false)] | ||||||
|  |     pub deleted: bool, | ||||||
|  | } | ||||||
|  |  | ||||||
| #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] | #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] | ||||||
| pub struct ToggleKVResponse { | pub struct ToggleKVResponse { | ||||||
|     /// The identifier for the Merchant Account |     /// The identifier for the Merchant Account | ||||||
|  | |||||||
| @ -6,7 +6,9 @@ | |||||||
| use std::fmt::Display; | use std::fmt::Display; | ||||||
|  |  | ||||||
| use crate::{ | use crate::{ | ||||||
|     date_time, generate_id_with_default_len, |     date_time, | ||||||
|  |     errors::{CustomResult, ValidationError}, | ||||||
|  |     generate_id_with_default_len, | ||||||
|     id_type::{AlphaNumericId, LengthId}, |     id_type::{AlphaNumericId, LengthId}, | ||||||
|     new_type::MerchantName, |     new_type::MerchantName, | ||||||
|     types::keymanager, |     types::keymanager, | ||||||
| @ -80,6 +82,11 @@ impl MerchantId { | |||||||
|         let length_id = LengthId::new_unchecked(alphanumeric_id); |         let length_id = LengthId::new_unchecked(alphanumeric_id); | ||||||
|         Self(length_id) |         Self(length_id) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Get a merchant id from String | ||||||
|  |     pub fn wrap(merchant_id: String) -> CustomResult<Self, ValidationError> { | ||||||
|  |         Self::try_from(std::borrow::Cow::from(merchant_id)) | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| impl From<MerchantId> for keymanager::Identifier { | impl From<MerchantId> for keymanager::Identifier { | ||||||
|  | |||||||
| @ -102,11 +102,11 @@ Never share your secret api keys. Keep them guarded and secure. | |||||||
|         routes::merchant_account::merchant_account_kv_status, |         routes::merchant_account::merchant_account_kv_status, | ||||||
|  |  | ||||||
|         // Routes for merchant connector account |         // Routes for merchant connector account | ||||||
|         routes::merchant_connector_account::payment_connector_create, |         routes::merchant_connector_account::connector_create, | ||||||
|         routes::merchant_connector_account::payment_connector_retrieve, |         routes::merchant_connector_account::connector_retrieve, | ||||||
|         routes::merchant_connector_account::payment_connector_list, |         routes::merchant_connector_account::payment_connector_list, | ||||||
|         routes::merchant_connector_account::payment_connector_update, |         routes::merchant_connector_account::connector_update, | ||||||
|         routes::merchant_connector_account::payment_connector_delete, |         routes::merchant_connector_account::connector_delete, | ||||||
|  |  | ||||||
|         //Routes for gsm |         //Routes for gsm | ||||||
|         routes::gsm::create_gsm_rule, |         routes::gsm::create_gsm_rule, | ||||||
|  | |||||||
| @ -58,7 +58,7 @@ | |||||||
|     operation_id = "Create a Merchant Connector", |     operation_id = "Create a Merchant Connector", | ||||||
|     security(("admin_api_key" = [])) |     security(("admin_api_key" = [])) | ||||||
| )] | )] | ||||||
| pub async fn payment_connector_create() {} | pub async fn connector_create() {} | ||||||
|  |  | ||||||
| /// Merchant Connector - Retrieve | /// Merchant Connector - Retrieve | ||||||
| /// | /// | ||||||
| @ -79,7 +79,7 @@ pub async fn payment_connector_create() {} | |||||||
|     operation_id = "Retrieve a Merchant Connector", |     operation_id = "Retrieve a Merchant Connector", | ||||||
|     security(("admin_api_key" = [])) |     security(("admin_api_key" = [])) | ||||||
| )] | )] | ||||||
| pub async fn payment_connector_retrieve() {} | pub async fn connector_retrieve() {} | ||||||
|  |  | ||||||
| /// Merchant Connector - List | /// Merchant Connector - List | ||||||
| /// | /// | ||||||
| @ -146,7 +146,7 @@ pub async fn payment_connector_list() {} | |||||||
|    operation_id = "Update a Merchant Connector", |    operation_id = "Update a Merchant Connector", | ||||||
|    security(("admin_api_key" = [])) |    security(("admin_api_key" = [])) | ||||||
| )] | )] | ||||||
| pub async fn payment_connector_update() {} | pub async fn connector_update() {} | ||||||
|  |  | ||||||
| /// Merchant Connector - Delete | /// Merchant Connector - Delete | ||||||
| /// | /// | ||||||
| @ -167,4 +167,4 @@ pub async fn payment_connector_update() {} | |||||||
|     operation_id = "Delete a Merchant Connector", |     operation_id = "Delete a Merchant Connector", | ||||||
|     security(("admin_api_key" = [])) |     security(("admin_api_key" = [])) | ||||||
| )] | )] | ||||||
| pub async fn payment_connector_delete() {} | pub async fn connector_delete() {} | ||||||
|  | |||||||
| @ -1930,7 +1930,7 @@ impl MerchantConnectorAccountUpdateBridge for api_models::admin::MerchantConnect | |||||||
|         key_store: &domain::MerchantKeyStore, |         key_store: &domain::MerchantKeyStore, | ||||||
|         key_manager_state: &KeyManagerState, |         key_manager_state: &KeyManagerState, | ||||||
|     ) -> RouterResult<domain::MerchantConnectorAccount> { |     ) -> RouterResult<domain::MerchantConnectorAccount> { | ||||||
|         db.find_by_merchant_connector_account_id( |         db.find_merchant_connector_account_by_id( | ||||||
|             key_manager_state, |             key_manager_state, | ||||||
|             merchant_connector_id, |             merchant_connector_id, | ||||||
|             key_store, |             key_store, | ||||||
| @ -2535,7 +2535,7 @@ impl MerchantConnectorAccountCreateBridge for api::MerchantConnectorCreate { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| pub async fn create_payment_connector( | pub async fn create_connector( | ||||||
|     state: SessionState, |     state: SessionState, | ||||||
|     req: api::MerchantConnectorCreate, |     req: api::MerchantConnectorCreate, | ||||||
|     merchant_id: &id_type::MerchantId, |     merchant_id: &id_type::MerchantId, | ||||||
| @ -2749,7 +2749,11 @@ async fn validate_pm_auth( | |||||||
|     Ok(services::ApplicationResponse::StatusOk) |     Ok(services::ApplicationResponse::StatusOk) | ||||||
| } | } | ||||||
|  |  | ||||||
| pub async fn retrieve_payment_connector( | #[cfg(all( | ||||||
|  |     any(feature = "v1", feature = "v2"), | ||||||
|  |     not(feature = "merchant_connector_account_v2") | ||||||
|  | ))] | ||||||
|  | pub async fn retrieve_connector( | ||||||
|     state: SessionState, |     state: SessionState, | ||||||
|     merchant_id: id_type::MerchantId, |     merchant_id: id_type::MerchantId, | ||||||
|     _profile_id: Option<String>, |     _profile_id: Option<String>, | ||||||
| @ -2771,10 +2775,6 @@ pub async fn retrieve_payment_connector( | |||||||
|         .await |         .await | ||||||
|         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?; |         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?; | ||||||
|  |  | ||||||
|     #[cfg(all( |  | ||||||
|         any(feature = "v1", feature = "v2"), |  | ||||||
|         not(feature = "merchant_connector_account_v2") |  | ||||||
|     ))] |  | ||||||
|     let mca = store |     let mca = store | ||||||
|         .find_by_merchant_connector_account_merchant_id_merchant_connector_id( |         .find_by_merchant_connector_account_merchant_id_merchant_connector_id( | ||||||
|             key_manager_state, |             key_manager_state, | ||||||
| @ -2787,11 +2787,46 @@ pub async fn retrieve_payment_connector( | |||||||
|             id: merchant_connector_id.clone(), |             id: merchant_connector_id.clone(), | ||||||
|         })?; |         })?; | ||||||
|  |  | ||||||
|  |     Ok(service_api::ApplicationResponse::Json( | ||||||
|  |         mca.foreign_try_into()?, | ||||||
|  |     )) | ||||||
|  | } | ||||||
|  |  | ||||||
| #[cfg(all(feature = "v2", feature = "merchant_connector_account_v2"))] | #[cfg(all(feature = "v2", feature = "merchant_connector_account_v2"))] | ||||||
|     let mca: domain::MerchantConnectorAccount = { | pub async fn retrieve_connector( | ||||||
|         let _ = &merchant_connector_id; |     state: SessionState, | ||||||
|         todo!() |     merchant_id: id_type::MerchantId, | ||||||
|     }; |     id: String, | ||||||
|  | ) -> RouterResponse<api_models::admin::MerchantConnectorResponse> { | ||||||
|  |     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_id, | ||||||
|  |             &store.get_master_key().to_vec().into(), | ||||||
|  |         ) | ||||||
|  |         .await | ||||||
|  |         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?; | ||||||
|  |  | ||||||
|  |     let mca = store | ||||||
|  |         .find_merchant_connector_account_by_id(key_manager_state, &id, &key_store) | ||||||
|  |         .await | ||||||
|  |         .to_not_found_response(errors::ApiErrorResponse::MerchantConnectorAccountNotFound { | ||||||
|  |             id: id.clone(), | ||||||
|  |         })?; | ||||||
|  |  | ||||||
|  |     // Validate if the merchant_id sent in the request is valid | ||||||
|  |     if mca.merchant_id != merchant_id { | ||||||
|  |         return Err(errors::ApiErrorResponse::InvalidRequestData { | ||||||
|  |             message: format!( | ||||||
|  |                 "Invalid merchant_id {} provided for merchant_connector_account {}", | ||||||
|  |                 merchant_id.get_string_repr(), | ||||||
|  |                 id | ||||||
|  |             ), | ||||||
|  |         } | ||||||
|  |         .into()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     Ok(service_api::ApplicationResponse::Json( |     Ok(service_api::ApplicationResponse::Json( | ||||||
|         mca.foreign_try_into()?, |         mca.foreign_try_into()?, | ||||||
| @ -2839,7 +2874,7 @@ pub async fn list_payment_connectors( | |||||||
|     Ok(service_api::ApplicationResponse::Json(response)) |     Ok(service_api::ApplicationResponse::Json(response)) | ||||||
| } | } | ||||||
|  |  | ||||||
| pub async fn update_payment_connector( | pub async fn update_connector( | ||||||
|     state: SessionState, |     state: SessionState, | ||||||
|     merchant_id: &id_type::MerchantId, |     merchant_id: &id_type::MerchantId, | ||||||
|     _profile_id: Option<String>, |     _profile_id: Option<String>, | ||||||
| @ -2916,7 +2951,11 @@ pub async fn update_payment_connector( | |||||||
|     Ok(service_api::ApplicationResponse::Json(response)) |     Ok(service_api::ApplicationResponse::Json(response)) | ||||||
| } | } | ||||||
|  |  | ||||||
| pub async fn delete_payment_connector( | #[cfg(all( | ||||||
|  |     any(feature = "v1", feature = "v2"), | ||||||
|  |     not(feature = "merchant_connector_account_v2") | ||||||
|  | ))] | ||||||
|  | pub async fn delete_connector( | ||||||
|     state: SessionState, |     state: SessionState, | ||||||
|     merchant_id: id_type::MerchantId, |     merchant_id: id_type::MerchantId, | ||||||
|     merchant_connector_id: String, |     merchant_connector_id: String, | ||||||
| @ -2937,10 +2976,6 @@ pub async fn delete_payment_connector( | |||||||
|         .await |         .await | ||||||
|         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?; |         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?; | ||||||
|  |  | ||||||
|     #[cfg(all( |  | ||||||
|         any(feature = "v1", feature = "v2"), |  | ||||||
|         not(feature = "merchant_connector_account_v2") |  | ||||||
|     ))] |  | ||||||
|     let _mca = db |     let _mca = db | ||||||
|         .find_by_merchant_connector_account_merchant_id_merchant_connector_id( |         .find_by_merchant_connector_account_merchant_id_merchant_connector_id( | ||||||
|             key_manager_state, |             key_manager_state, | ||||||
| @ -2953,16 +2988,6 @@ pub async fn delete_payment_connector( | |||||||
|             id: merchant_connector_id.clone(), |             id: merchant_connector_id.clone(), | ||||||
|         })?; |         })?; | ||||||
|  |  | ||||||
|     #[cfg(all(feature = "v2", feature = "merchant_connector_account_v2"))] |  | ||||||
|     { |  | ||||||
|         let _ = merchant_connector_id; |  | ||||||
|         todo!() |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     #[cfg(all( |  | ||||||
|         any(feature = "v1", feature = "v2"), |  | ||||||
|         not(feature = "merchant_connector_account_v2") |  | ||||||
|     ))] |  | ||||||
|     let is_deleted = db |     let is_deleted = db | ||||||
|         .delete_merchant_connector_account_by_merchant_id_merchant_connector_id( |         .delete_merchant_connector_account_by_merchant_id_merchant_connector_id( | ||||||
|             &merchant_id, |             &merchant_id, | ||||||
| @ -2973,9 +2998,6 @@ pub async fn delete_payment_connector( | |||||||
|             id: merchant_connector_id.clone(), |             id: merchant_connector_id.clone(), | ||||||
|         })?; |         })?; | ||||||
|  |  | ||||||
|     #[cfg(all(feature = "v2", feature = "merchant_connector_account_v2"))] |  | ||||||
|     let is_deleted = { todo!() }; |  | ||||||
|  |  | ||||||
|     let response = api::MerchantConnectorDeleteResponse { |     let response = api::MerchantConnectorDeleteResponse { | ||||||
|         merchant_id, |         merchant_id, | ||||||
|         merchant_connector_id, |         merchant_connector_id, | ||||||
| @ -2984,6 +3006,57 @@ pub async fn delete_payment_connector( | |||||||
|     Ok(service_api::ApplicationResponse::Json(response)) |     Ok(service_api::ApplicationResponse::Json(response)) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[cfg(all(feature = "v2", feature = "merchant_connector_account_v2"))] | ||||||
|  | pub async fn delete_connector( | ||||||
|  |     state: SessionState, | ||||||
|  |     merchant_id: id_type::MerchantId, | ||||||
|  |     id: String, | ||||||
|  | ) -> RouterResponse<api::MerchantConnectorDeleteResponse> { | ||||||
|  |     let db = state.store.as_ref(); | ||||||
|  |     let key_manager_state = &(&state).into(); | ||||||
|  |     let key_store = db | ||||||
|  |         .get_merchant_key_store_by_merchant_id( | ||||||
|  |             key_manager_state, | ||||||
|  |             &merchant_id, | ||||||
|  |             &db.get_master_key().to_vec().into(), | ||||||
|  |         ) | ||||||
|  |         .await | ||||||
|  |         .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?; | ||||||
|  |  | ||||||
|  |     let mca = db | ||||||
|  |         .find_merchant_connector_account_by_id(key_manager_state, &id, &key_store) | ||||||
|  |         .await | ||||||
|  |         .to_not_found_response(errors::ApiErrorResponse::MerchantConnectorAccountNotFound { | ||||||
|  |             id: id.clone(), | ||||||
|  |         })?; | ||||||
|  |  | ||||||
|  |     // Validate if the merchant_id sent in the request is valid | ||||||
|  |     if mca.merchant_id != merchant_id { | ||||||
|  |         return Err(errors::ApiErrorResponse::InvalidRequestData { | ||||||
|  |             message: format!( | ||||||
|  |                 "Invalid merchant_id {} provided for merchant_connector_account {}", | ||||||
|  |                 merchant_id.get_string_repr(), | ||||||
|  |                 id | ||||||
|  |             ), | ||||||
|  |         } | ||||||
|  |         .into()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     let is_deleted = db | ||||||
|  |         .delete_merchant_connector_account_by_id(&id) | ||||||
|  |         .await | ||||||
|  |         .to_not_found_response(errors::ApiErrorResponse::MerchantConnectorAccountNotFound { | ||||||
|  |             id: id.clone(), | ||||||
|  |         })?; | ||||||
|  |  | ||||||
|  |     let response = api::MerchantConnectorDeleteResponse { | ||||||
|  |         merchant_id, | ||||||
|  |         id, | ||||||
|  |         deleted: is_deleted, | ||||||
|  |     }; | ||||||
|  |     Ok(service_api::ApplicationResponse::Json(response)) | ||||||
|  | } | ||||||
|  |  | ||||||
| pub async fn kv_for_merchant( | pub async fn kv_for_merchant( | ||||||
|     state: SessionState, |     state: SessionState, | ||||||
|     merchant_id: id_type::MerchantId, |     merchant_id: id_type::MerchantId, | ||||||
|  | |||||||
| @ -180,8 +180,7 @@ pub async fn update_mca( | |||||||
|         merchant_id: merchant_id.clone(), |         merchant_id: merchant_id.clone(), | ||||||
|     }; |     }; | ||||||
|     let mca_response = |     let mca_response = | ||||||
|         admin::update_payment_connector(state.clone(), &merchant_id, None, &connector_id, request) |         admin::update_connector(state.clone(), &merchant_id, None, &connector_id, request).await?; | ||||||
|             .await?; |  | ||||||
|  |  | ||||||
|     match mca_response { |     match mca_response { | ||||||
|         ApplicationResponse::Json(mca_data) => Ok(mca_data), |         ApplicationResponse::Json(mca_data) => Ok(mca_data), | ||||||
|  | |||||||
| @ -1114,14 +1114,14 @@ impl MerchantConnectorAccountInterface for KafkaStore { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     #[cfg(all(feature = "v2", feature = "merchant_connector_account_v2"))] |     #[cfg(all(feature = "v2", feature = "merchant_connector_account_v2"))] | ||||||
|     async fn find_by_merchant_connector_account_id( |     async fn find_merchant_connector_account_by_id( | ||||||
|         &self, |         &self, | ||||||
|         state: &KeyManagerState, |         state: &KeyManagerState, | ||||||
|         id: &str, |         id: &str, | ||||||
|         key_store: &domain::MerchantKeyStore, |         key_store: &domain::MerchantKeyStore, | ||||||
|     ) -> CustomResult<domain::MerchantConnectorAccount, errors::StorageError> { |     ) -> CustomResult<domain::MerchantConnectorAccount, errors::StorageError> { | ||||||
|         self.diesel_store |         self.diesel_store | ||||||
|             .find_by_merchant_connector_account_id(state, id, key_store) |             .find_merchant_connector_account_by_id(state, id, key_store) | ||||||
|             .await |             .await | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
| @ -178,7 +178,7 @@ where | |||||||
|     ) -> CustomResult<domain::MerchantConnectorAccount, errors::StorageError>; |     ) -> CustomResult<domain::MerchantConnectorAccount, errors::StorageError>; | ||||||
|  |  | ||||||
|     #[cfg(all(feature = "v2", feature = "merchant_connector_account_v2"))] |     #[cfg(all(feature = "v2", feature = "merchant_connector_account_v2"))] | ||||||
|     async fn find_by_merchant_connector_account_id( |     async fn find_merchant_connector_account_by_id( | ||||||
|         &self, |         &self, | ||||||
|         state: &KeyManagerState, |         state: &KeyManagerState, | ||||||
|         id: &str, |         id: &str, | ||||||
| @ -439,7 +439,7 @@ impl MerchantConnectorAccountInterface for Store { | |||||||
|  |  | ||||||
|     #[instrument(skip_all)] |     #[instrument(skip_all)] | ||||||
|     #[cfg(all(feature = "v2", feature = "merchant_connector_account_v2"))] |     #[cfg(all(feature = "v2", feature = "merchant_connector_account_v2"))] | ||||||
|     async fn find_by_merchant_connector_account_id( |     async fn find_merchant_connector_account_by_id( | ||||||
|         &self, |         &self, | ||||||
|         state: &KeyManagerState, |         state: &KeyManagerState, | ||||||
|         id: &str, |         id: &str, | ||||||
| @ -1106,7 +1106,7 @@ impl MerchantConnectorAccountInterface for MockDb { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     #[cfg(all(feature = "v2", feature = "merchant_connector_account_v2"))] |     #[cfg(all(feature = "v2", feature = "merchant_connector_account_v2"))] | ||||||
|     async fn find_by_merchant_connector_account_id( |     async fn find_merchant_connector_account_by_id( | ||||||
|         &self, |         &self, | ||||||
|         state: &KeyManagerState, |         state: &KeyManagerState, | ||||||
|         id: &str, |         id: &str, | ||||||
|  | |||||||
| @ -1,7 +1,13 @@ | |||||||
| use actix_web::{web, HttpRequest, HttpResponse}; | use actix_web::{web, HttpRequest, HttpResponse}; | ||||||
|  | #[cfg(all(feature = "v2", feature = "merchant_connector_account_v2"))] | ||||||
|  | use error_stack::ResultExt; | ||||||
|  | #[cfg(all(feature = "v2", feature = "merchant_connector_account_v2"))] | ||||||
|  | use hyperswitch_domain_models::errors::api_error_response::ApiErrorResponse; | ||||||
| use router_env::{instrument, tracing, Flow}; | use router_env::{instrument, tracing, Flow}; | ||||||
|  |  | ||||||
| use super::app::AppState; | use super::app::AppState; | ||||||
|  | #[cfg(all(feature = "v2", feature = "merchant_connector_account_v2"))] | ||||||
|  | use crate::headers; | ||||||
| use crate::{ | use crate::{ | ||||||
|     core::{admin::*, api_locking}, |     core::{admin::*, api_locking}, | ||||||
|     services::{api, authentication as auth, authorization::permissions::Permission}, |     services::{api, authentication as auth, authorization::permissions::Permission}, | ||||||
| @ -240,6 +246,33 @@ pub async fn delete_merchant_account( | |||||||
|     ) |     ) | ||||||
|     .await |     .await | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[cfg(all(feature = "v2", feature = "merchant_connector_account_v2"))] | ||||||
|  | struct HeaderMapStruct<'a> { | ||||||
|  |     headers: &'a actix_http::header::HeaderMap, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[cfg(all(feature = "v2", feature = "merchant_connector_account_v2"))] | ||||||
|  | impl<'a> HeaderMapStruct<'a> { | ||||||
|  |     pub fn get_mandatory_header_value_by_key( | ||||||
|  |         &self, | ||||||
|  |         key: String, | ||||||
|  |     ) -> Result<&str, error_stack::Report<ApiErrorResponse>> { | ||||||
|  |         self.headers | ||||||
|  |             .get(&key) | ||||||
|  |             .ok_or(ApiErrorResponse::InvalidRequestData { | ||||||
|  |                 message: format!("Missing header key: {}", key), | ||||||
|  |             }) | ||||||
|  |             .attach_printable(format!("Failed to find header key: {}", key))? | ||||||
|  |             .to_str() | ||||||
|  |             .change_context(ApiErrorResponse::InternalServerError) | ||||||
|  |             .attach_printable(format!( | ||||||
|  |                 "Failed to convert header value to string for header key: {}", | ||||||
|  |                 key | ||||||
|  |             )) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| /// Merchant Connector - Create | /// Merchant Connector - Create | ||||||
| /// | /// | ||||||
| /// Create a new Merchant Connector for the merchant account. The connector could be a payment processor / facilitator / acquirer or specialized services like Fraud / Accounting etc." | /// Create a new Merchant Connector for the merchant account. The connector could be a payment processor / facilitator / acquirer or specialized services like Fraud / Accounting etc." | ||||||
| @ -260,7 +293,7 @@ pub async fn delete_merchant_account( | |||||||
|     security(("admin_api_key" = [])) |     security(("admin_api_key" = [])) | ||||||
| )] | )] | ||||||
| #[instrument(skip_all, fields(flow = ?Flow::MerchantConnectorsCreate))] | #[instrument(skip_all, fields(flow = ?Flow::MerchantConnectorsCreate))] | ||||||
| pub async fn payment_connector_create( | pub async fn connector_create( | ||||||
|     state: web::Data<AppState>, |     state: web::Data<AppState>, | ||||||
|     req: HttpRequest, |     req: HttpRequest, | ||||||
|     path: web::Path<common_utils::id_type::MerchantId>, |     path: web::Path<common_utils::id_type::MerchantId>, | ||||||
| @ -274,7 +307,7 @@ pub async fn payment_connector_create( | |||||||
|         state, |         state, | ||||||
|         &req, |         &req, | ||||||
|         payload, |         payload, | ||||||
|         |state, _, req, _| create_payment_connector(state, req, &merchant_id), |         |state, _, req, _| create_connector(state, req, &merchant_id), | ||||||
|         auth::auth_type( |         auth::auth_type( | ||||||
|             &auth::AdminApiAuth, |             &auth::AdminApiAuth, | ||||||
|             &auth::JWTAuthMerchantFromRoute { |             &auth::JWTAuthMerchantFromRoute { | ||||||
| @ -304,7 +337,7 @@ pub async fn payment_connector_create( | |||||||
|     security(("admin_api_key" = [])) |     security(("admin_api_key" = [])) | ||||||
| )] | )] | ||||||
| #[instrument(skip_all, fields(flow = ?Flow::MerchantConnectorsCreate))] | #[instrument(skip_all, fields(flow = ?Flow::MerchantConnectorsCreate))] | ||||||
| pub async fn payment_connector_create( | pub async fn connector_create( | ||||||
|     state: web::Data<AppState>, |     state: web::Data<AppState>, | ||||||
|     req: HttpRequest, |     req: HttpRequest, | ||||||
|     json_payload: web::Json<admin::MerchantConnectorCreate>, |     json_payload: web::Json<admin::MerchantConnectorCreate>, | ||||||
| @ -317,7 +350,7 @@ pub async fn payment_connector_create( | |||||||
|         state, |         state, | ||||||
|         &req, |         &req, | ||||||
|         payload, |         payload, | ||||||
|         |state, _, req, _| create_payment_connector(state, req, &merchant_id), |         |state, _, req, _| create_connector(state, req, &merchant_id), | ||||||
|         auth::auth_type( |         auth::auth_type( | ||||||
|             &auth::AdminApiAuth, |             &auth::AdminApiAuth, | ||||||
|             &auth::JWTAuthMerchantFromRoute { |             &auth::JWTAuthMerchantFromRoute { | ||||||
| @ -333,6 +366,10 @@ pub async fn payment_connector_create( | |||||||
| /// Merchant Connector - Retrieve | /// Merchant Connector - Retrieve | ||||||
| /// | /// | ||||||
| /// Retrieve Merchant Connector Details | /// Retrieve Merchant Connector Details | ||||||
|  | #[cfg(all( | ||||||
|  |     any(feature = "v1", feature = "v2"), | ||||||
|  |     not(feature = "merchant_connector_account_v2") | ||||||
|  | ))] | ||||||
| #[utoipa::path( | #[utoipa::path( | ||||||
|     get, |     get, | ||||||
|     path = "/accounts/{account_id}/connectors/{connector_id}", |     path = "/accounts/{account_id}/connectors/{connector_id}", | ||||||
| @ -350,7 +387,7 @@ pub async fn payment_connector_create( | |||||||
|     security(("admin_api_key" = [])) |     security(("admin_api_key" = [])) | ||||||
| )] | )] | ||||||
| #[instrument(skip_all, fields(flow = ?Flow::MerchantConnectorsRetrieve))] | #[instrument(skip_all, fields(flow = ?Flow::MerchantConnectorsRetrieve))] | ||||||
| pub async fn payment_connector_retrieve( | pub async fn connector_retrieve( | ||||||
|     state: web::Data<AppState>, |     state: web::Data<AppState>, | ||||||
|     req: HttpRequest, |     req: HttpRequest, | ||||||
|     path: web::Path<(common_utils::id_type::MerchantId, String)>, |     path: web::Path<(common_utils::id_type::MerchantId, String)>, | ||||||
| @ -369,7 +406,7 @@ pub async fn payment_connector_retrieve( | |||||||
|         &req, |         &req, | ||||||
|         payload, |         payload, | ||||||
|         |state, _, req, _| { |         |state, _, req, _| { | ||||||
|             retrieve_payment_connector(state, req.merchant_id, None, req.merchant_connector_id) |             retrieve_connector(state, req.merchant_id, None, req.merchant_connector_id) | ||||||
|         }, |         }, | ||||||
|         auth::auth_type( |         auth::auth_type( | ||||||
|             &auth::AdminApiAuth, |             &auth::AdminApiAuth, | ||||||
| @ -383,6 +420,72 @@ pub async fn payment_connector_retrieve( | |||||||
|     ) |     ) | ||||||
|     .await |     .await | ||||||
| } | } | ||||||
|  | /// Merchant Connector - Retrieve | ||||||
|  | /// | ||||||
|  | /// Retrieve Merchant Connector Details | ||||||
|  | #[cfg(all(feature = "v2", feature = "merchant_connector_account_v2"))] | ||||||
|  | #[utoipa::path( | ||||||
|  |     get, | ||||||
|  |     path = "/connector_accounts/{id}", | ||||||
|  |     params( | ||||||
|  |         ("id" = i32, Path, description = "The unique identifier for the Merchant Connector") | ||||||
|  |     ), | ||||||
|  |     responses( | ||||||
|  |         (status = 200, description = "Merchant Connector retrieved successfully", body = MerchantConnectorResponse), | ||||||
|  |         (status = 404, description = "Merchant Connector does not exist in records"), | ||||||
|  |         (status = 401, description = "Unauthorized request") | ||||||
|  |     ), | ||||||
|  |     tag = "Merchant Connector Account", | ||||||
|  |     operation_id = "Retrieve a Merchant Connector", | ||||||
|  |     security(("admin_api_key" = [])) | ||||||
|  | )] | ||||||
|  | #[instrument(skip_all, fields(flow = ?Flow::MerchantConnectorsRetrieve))] | ||||||
|  | pub async fn connector_retrieve( | ||||||
|  |     state: web::Data<AppState>, | ||||||
|  |     req: HttpRequest, | ||||||
|  |     path: web::Path<String>, | ||||||
|  | ) -> HttpResponse { | ||||||
|  |     let flow = Flow::MerchantConnectorsRetrieve; | ||||||
|  |     let id = path.into_inner(); | ||||||
|  |     let payload = web::Json(admin::MerchantConnectorId { id: id.clone() }).into_inner(); | ||||||
|  |  | ||||||
|  |     let header_map = HeaderMapStruct { | ||||||
|  |         headers: req.headers(), | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     let merchant_id = match header_map | ||||||
|  |         .get_mandatory_header_value_by_key(headers::X_MERCHANT_ID.into()) | ||||||
|  |         .map(|val| val.to_owned()) | ||||||
|  |         .and_then(|merchant_id| { | ||||||
|  |             common_utils::id_type::MerchantId::wrap(merchant_id) | ||||||
|  |                 .change_context(ApiErrorResponse::InternalServerError) | ||||||
|  |                 .attach_printable( | ||||||
|  |                     "Error while converting MerchantId from merchant_id string header", | ||||||
|  |                 ) | ||||||
|  |         }) { | ||||||
|  |         Ok(val) => val, | ||||||
|  |         Err(err) => { | ||||||
|  |             return api::log_and_return_error_response(err); | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  |     api::server_wrap( | ||||||
|  |         flow, | ||||||
|  |         state, | ||||||
|  |         &req, | ||||||
|  |         payload, | ||||||
|  |         |state, _, req, _| retrieve_connector(state, merchant_id.clone(), req.id.clone()), | ||||||
|  |         auth::auth_type( | ||||||
|  |             &auth::AdminApiAuth, | ||||||
|  |             &auth::JWTAuthMerchantFromRoute { | ||||||
|  |                 merchant_id: merchant_id.clone(), | ||||||
|  |                 required_permission: Permission::MerchantConnectorAccountRead, | ||||||
|  |             }, | ||||||
|  |             req.headers(), | ||||||
|  |         ), | ||||||
|  |         api_locking::LockAction::NotApplicable, | ||||||
|  |     ) | ||||||
|  |     .await | ||||||
|  | } | ||||||
| /// Merchant Connector - List | /// Merchant Connector - List | ||||||
| /// | /// | ||||||
| /// List Merchant Connector Details for the merchant | /// List Merchant Connector Details for the merchant | ||||||
| @ -453,7 +556,7 @@ pub async fn payment_connector_list( | |||||||
|    security(("admin_api_key" = [])) |    security(("admin_api_key" = [])) | ||||||
| )] | )] | ||||||
| #[instrument(skip_all, fields(flow = ?Flow::MerchantConnectorsUpdate))] | #[instrument(skip_all, fields(flow = ?Flow::MerchantConnectorsUpdate))] | ||||||
| pub async fn payment_connector_update( | pub async fn connector_update( | ||||||
|     state: web::Data<AppState>, |     state: web::Data<AppState>, | ||||||
|     req: HttpRequest, |     req: HttpRequest, | ||||||
|     path: web::Path<(common_utils::id_type::MerchantId, String)>, |     path: web::Path<(common_utils::id_type::MerchantId, String)>, | ||||||
| @ -467,9 +570,7 @@ pub async fn payment_connector_update( | |||||||
|         state, |         state, | ||||||
|         &req, |         &req, | ||||||
|         json_payload.into_inner(), |         json_payload.into_inner(), | ||||||
|         |state, _, req, _| { |         |state, _, req, _| update_connector(state, &merchant_id, None, &merchant_connector_id, req), | ||||||
|             update_payment_connector(state, &merchant_id, None, &merchant_connector_id, req) |  | ||||||
|         }, |  | ||||||
|         auth::auth_type( |         auth::auth_type( | ||||||
|             &auth::AdminApiAuth, |             &auth::AdminApiAuth, | ||||||
|             &auth::JWTAuthMerchantFromRoute { |             &auth::JWTAuthMerchantFromRoute { | ||||||
| @ -504,7 +605,7 @@ pub async fn payment_connector_update( | |||||||
|    security(("admin_api_key" = [])) |    security(("admin_api_key" = [])) | ||||||
| )] | )] | ||||||
| #[instrument(skip_all, fields(flow = ?Flow::MerchantConnectorsUpdate))] | #[instrument(skip_all, fields(flow = ?Flow::MerchantConnectorsUpdate))] | ||||||
| pub async fn payment_connector_update( | pub async fn connector_update( | ||||||
|     state: web::Data<AppState>, |     state: web::Data<AppState>, | ||||||
|     req: HttpRequest, |     req: HttpRequest, | ||||||
|     path: web::Path<String>, |     path: web::Path<String>, | ||||||
| @ -520,7 +621,7 @@ pub async fn payment_connector_update( | |||||||
|         state, |         state, | ||||||
|         &req, |         &req, | ||||||
|         payload, |         payload, | ||||||
|         |state, _, req, _| update_payment_connector(state, &merchant_id, &id, req), |         |state, _, req, _| update_connector(state, &merchant_id, None, &id, req), | ||||||
|         auth::auth_type( |         auth::auth_type( | ||||||
|             &auth::AdminApiAuth, |             &auth::AdminApiAuth, | ||||||
|             &auth::JWTAuthMerchantFromRoute { |             &auth::JWTAuthMerchantFromRoute { | ||||||
| @ -536,6 +637,10 @@ pub async fn payment_connector_update( | |||||||
| /// Merchant Connector - Delete | /// Merchant Connector - Delete | ||||||
| /// | /// | ||||||
| /// Delete or Detach a Merchant Connector from Merchant Account | /// Delete or Detach a Merchant Connector from Merchant Account | ||||||
|  | #[cfg(all( | ||||||
|  |     any(feature = "v1", feature = "v2"), | ||||||
|  |     not(feature = "merchant_connector_account_v2") | ||||||
|  | ))] | ||||||
| #[utoipa::path( | #[utoipa::path( | ||||||
|     delete, |     delete, | ||||||
|     path = "/accounts/{account_id}/connectors/{connector_id}", |     path = "/accounts/{account_id}/connectors/{connector_id}", | ||||||
| @ -553,7 +658,7 @@ pub async fn payment_connector_update( | |||||||
|     security(("admin_api_key" = [])) |     security(("admin_api_key" = [])) | ||||||
| )] | )] | ||||||
| #[instrument(skip_all, fields(flow = ?Flow::MerchantConnectorsDelete))] | #[instrument(skip_all, fields(flow = ?Flow::MerchantConnectorsDelete))] | ||||||
| pub async fn payment_connector_delete( | pub async fn connector_delete( | ||||||
|     state: web::Data<AppState>, |     state: web::Data<AppState>, | ||||||
|     req: HttpRequest, |     req: HttpRequest, | ||||||
|     path: web::Path<(common_utils::id_type::MerchantId, String)>, |     path: web::Path<(common_utils::id_type::MerchantId, String)>, | ||||||
| @ -571,9 +676,7 @@ pub async fn payment_connector_delete( | |||||||
|         state, |         state, | ||||||
|         &req, |         &req, | ||||||
|         payload, |         payload, | ||||||
|         |state, _, req, _| { |         |state, _, req, _| delete_connector(state, req.merchant_id, req.merchant_connector_id), | ||||||
|             delete_payment_connector(state, req.merchant_id, req.merchant_connector_id) |  | ||||||
|         }, |  | ||||||
|         auth::auth_type( |         auth::auth_type( | ||||||
|             &auth::AdminApiAuth, |             &auth::AdminApiAuth, | ||||||
|             &auth::JWTAuthMerchantFromRoute { |             &auth::JWTAuthMerchantFromRoute { | ||||||
| @ -586,6 +689,71 @@ pub async fn payment_connector_delete( | |||||||
|     )) |     )) | ||||||
|     .await |     .await | ||||||
| } | } | ||||||
|  | /// Merchant Connector - Delete | ||||||
|  | /// | ||||||
|  | /// Delete or Detach a Merchant Connector from Merchant Account | ||||||
|  | #[cfg(all(feature = "v2", feature = "merchant_connector_account_v2"))] | ||||||
|  | #[utoipa::path( | ||||||
|  |     delete, | ||||||
|  |     path = "/connector_accounts/{id}", | ||||||
|  |     params( | ||||||
|  |         ("id" = i32, Path, description = "The unique identifier for the Merchant Connector") | ||||||
|  |     ), | ||||||
|  |     responses( | ||||||
|  |         (status = 200, description = "Merchant Connector Deleted", body = MerchantConnectorDeleteResponse), | ||||||
|  |         (status = 404, description = "Merchant Connector does not exist in records"), | ||||||
|  |         (status = 401, description = "Unauthorized request") | ||||||
|  |     ), | ||||||
|  |     tag = "Merchant Connector Account", | ||||||
|  |     operation_id = "Delete a Merchant Connector", | ||||||
|  |     security(("admin_api_key" = [])) | ||||||
|  | )] | ||||||
|  | #[instrument(skip_all, fields(flow = ?Flow::MerchantConnectorsDelete))] | ||||||
|  | pub async fn connector_delete( | ||||||
|  |     state: web::Data<AppState>, | ||||||
|  |     req: HttpRequest, | ||||||
|  |     path: web::Path<String>, | ||||||
|  | ) -> HttpResponse { | ||||||
|  |     let flow = Flow::MerchantConnectorsDelete; | ||||||
|  |     let id = path.into_inner(); | ||||||
|  |  | ||||||
|  |     let payload = web::Json(admin::MerchantConnectorId { id: id.clone() }).into_inner(); | ||||||
|  |     let header_map = HeaderMapStruct { | ||||||
|  |         headers: req.headers(), | ||||||
|  |     }; | ||||||
|  |     let merchant_id = match header_map | ||||||
|  |         .get_mandatory_header_value_by_key(headers::X_MERCHANT_ID.into()) | ||||||
|  |         .map(|val| val.to_owned()) | ||||||
|  |         .and_then(|merchant_id| { | ||||||
|  |             common_utils::id_type::MerchantId::wrap(merchant_id) | ||||||
|  |                 .change_context(ApiErrorResponse::InternalServerError) | ||||||
|  |                 .attach_printable( | ||||||
|  |                     "Error while converting MerchantId from merchant_id string header", | ||||||
|  |                 ) | ||||||
|  |         }) { | ||||||
|  |         Ok(val) => val, | ||||||
|  |         Err(err) => { | ||||||
|  |             return api::log_and_return_error_response(err); | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  |     Box::pin(api::server_wrap( | ||||||
|  |         flow, | ||||||
|  |         state, | ||||||
|  |         &req, | ||||||
|  |         payload, | ||||||
|  |         |state, _, req, _| delete_connector(state, merchant_id.clone(), req.id), | ||||||
|  |         auth::auth_type( | ||||||
|  |             &auth::AdminApiAuth, | ||||||
|  |             &auth::JWTAuthMerchantFromRoute { | ||||||
|  |                 merchant_id: merchant_id.clone(), | ||||||
|  |                 required_permission: Permission::MerchantConnectorAccountWrite, | ||||||
|  |             }, | ||||||
|  |             req.headers(), | ||||||
|  |         ), | ||||||
|  |         api_locking::LockAction::NotApplicable, | ||||||
|  |     )) | ||||||
|  |     .await | ||||||
|  | } | ||||||
| /// Merchant Account - Toggle KV | /// Merchant Account - Toggle KV | ||||||
| /// | /// | ||||||
| /// Toggle KV mode for the Merchant Account | /// Toggle KV mode for the Merchant Account | ||||||
|  | |||||||
| @ -1181,8 +1181,10 @@ impl MerchantConnectorAccount { | |||||||
|             use super::admin::*; |             use super::admin::*; | ||||||
|  |  | ||||||
|             route = route |             route = route | ||||||
|                 .service(web::resource("").route(web::post().to(payment_connector_create))) |                 .service(web::resource("").route(web::post().to(connector_create))) | ||||||
|                 .service(web::resource("/{id}").route(web::post().to(payment_connector_update))); |                 .service(web::resource("/{id}").route(web::post().to(connector_update))) | ||||||
|  |                 .service(web::resource("/{id}").route(web::get().to(connector_retrieve))) | ||||||
|  |                 .service(web::resource("/{id}").route(web::delete().to(connector_delete))); | ||||||
|         } |         } | ||||||
|         route |         route | ||||||
|     } |     } | ||||||
| @ -1208,14 +1210,14 @@ impl MerchantConnectorAccount { | |||||||
|                 ) |                 ) | ||||||
|                 .service( |                 .service( | ||||||
|                     web::resource("/{merchant_id}/connectors") |                     web::resource("/{merchant_id}/connectors") | ||||||
|                         .route(web::post().to(payment_connector_create)) |                         .route(web::post().to(connector_create)) | ||||||
|                         .route(web::get().to(payment_connector_list)), |                         .route(web::get().to(payment_connector_list)), | ||||||
|                 ) |                 ) | ||||||
|                 .service( |                 .service( | ||||||
|                     web::resource("/{merchant_id}/connectors/{merchant_connector_id}") |                     web::resource("/{merchant_id}/connectors/{merchant_connector_id}") | ||||||
|                         .route(web::get().to(payment_connector_retrieve)) |                         .route(web::get().to(connector_retrieve)) | ||||||
|                         .route(web::post().to(payment_connector_update)) |                         .route(web::post().to(connector_update)) | ||||||
|                         .route(web::delete().to(payment_connector_delete)), |                         .route(web::delete().to(connector_delete)), | ||||||
|                 ); |                 ); | ||||||
|         } |         } | ||||||
|         #[cfg(feature = "oltp")] |         #[cfg(feature = "oltp")] | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user