mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-10-31 01:57:45 +08:00 
			
		
		
		
	revert: connector_label in webhook url is reverted back to connector_name (#1779)
This commit is contained in:
		| @ -70,6 +70,29 @@ impl MerchantConnectorAccount { | ||||
|         .await | ||||
|     } | ||||
|  | ||||
|     #[instrument(skip(conn))] | ||||
|     pub async fn find_by_merchant_id_connector_name( | ||||
|         conn: &PgPooledConn, | ||||
|         merchant_id: &str, | ||||
|         connector_name: &str, | ||||
|     ) -> StorageResult<Vec<Self>> { | ||||
|         generics::generic_filter::< | ||||
|             <Self as HasTable>::Table, | ||||
|             _, | ||||
|             <<Self as HasTable>::Table as Table>::PrimaryKey, | ||||
|             _, | ||||
|         >( | ||||
|             conn, | ||||
|             dsl::merchant_id | ||||
|                 .eq(merchant_id.to_owned()) | ||||
|                 .and(dsl::connector_name.eq(connector_name.to_owned())), | ||||
|             None, | ||||
|             None, | ||||
|             None, | ||||
|         ) | ||||
|         .await | ||||
|     } | ||||
|  | ||||
|     #[instrument(skip(conn))] | ||||
|     pub async fn find_by_merchant_id_merchant_connector_id( | ||||
|         conn: &PgPooledConn, | ||||
|  | ||||
| @ -101,7 +101,7 @@ impl Webhooks { | ||||
|         web::scope("/webhooks") | ||||
|             .app_data(web::Data::new(config)) | ||||
|             .service( | ||||
|                 web::resource("/{merchant_id}/{connector_label}") | ||||
|                 web::resource("/{merchant_id}/{connector_name}") | ||||
|                     .route( | ||||
|                         web::post().to(webhooks::receive_incoming_webhook::<StripeOutgoingWebhook>), | ||||
|                     ) | ||||
|  | ||||
| @ -630,18 +630,9 @@ pub async fn webhooks_core<W: types::OutgoingWebhookType>( | ||||
|     req: &actix_web::HttpRequest, | ||||
|     merchant_account: domain::MerchantAccount, | ||||
|     key_store: domain::MerchantKeyStore, | ||||
|     connector_label: &str, | ||||
|     connector_name: &str, | ||||
|     body: actix_web::web::Bytes, | ||||
| ) -> RouterResponse<serde_json::Value> { | ||||
|     let connector_name = connector_label | ||||
|         .split('_') //connector_name will be the first string after splitting connector_label | ||||
|         .next() | ||||
|         .ok_or(errors::ApiErrorResponse::InvalidDataValue { | ||||
|             field_name: "connector_label", | ||||
|         }) | ||||
|         .into_report() | ||||
|         .attach_printable("Failed to infer connector_name from connector_label")?; | ||||
|  | ||||
|     metrics::WEBHOOK_INCOMING_COUNT.add( | ||||
|         &metrics::CONTEXT, | ||||
|         1, | ||||
| @ -688,7 +679,7 @@ pub async fn webhooks_core<W: types::OutgoingWebhookType>( | ||||
|  | ||||
|     let process_webhook_further = utils::lookup_webhook_event( | ||||
|         &*state.store, | ||||
|         connector_label, | ||||
|         connector_name, | ||||
|         &merchant_account.merchant_id, | ||||
|         &event_type, | ||||
|     ) | ||||
| @ -704,7 +695,7 @@ pub async fn webhooks_core<W: types::OutgoingWebhookType>( | ||||
|                 &*state.store, | ||||
|                 &request_details, | ||||
|                 &merchant_account.merchant_id, | ||||
|                 connector_label, | ||||
|                 connector_name, | ||||
|                 &key_store, | ||||
|             ) | ||||
|             .await | ||||
|  | ||||
| @ -1,4 +1,7 @@ | ||||
| use std::cmp::Ordering; | ||||
|  | ||||
| use common_utils::ext_traits::{AsyncExt, ByteSliceExt, Encode}; | ||||
| use diesel_models::errors as storage_errors; | ||||
| use error_stack::{IntoReport, ResultExt}; | ||||
|  | ||||
| use super::{MockDb, Store}; | ||||
| @ -119,6 +122,13 @@ where | ||||
|         key_store: &domain::MerchantKeyStore, | ||||
|     ) -> CustomResult<domain::MerchantConnectorAccount, errors::StorageError>; | ||||
|  | ||||
|     async fn find_merchant_connector_account_by_merchant_id_connector_name( | ||||
|         &self, | ||||
|         merchant_id: &str, | ||||
|         connector_name: &str, | ||||
|         key_store: &domain::MerchantKeyStore, | ||||
|     ) -> CustomResult<domain::MerchantConnectorAccount, errors::StorageError>; | ||||
|  | ||||
|     async fn insert_merchant_connector_account( | ||||
|         &self, | ||||
|         t: domain::MerchantConnectorAccount, | ||||
| @ -200,6 +210,53 @@ impl MerchantConnectorAccountInterface for Store { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     async fn find_merchant_connector_account_by_merchant_id_connector_name( | ||||
|         &self, | ||||
|         merchant_id: &str, | ||||
|         connector_name: &str, | ||||
|         key_store: &domain::MerchantKeyStore, | ||||
|     ) -> CustomResult<domain::MerchantConnectorAccount, errors::StorageError> { | ||||
|         let find_call = || async { | ||||
|             let conn = connection::pg_connection_read(self).await?; | ||||
|             storage::MerchantConnectorAccount::find_by_merchant_id_connector_name( | ||||
|                 &conn, | ||||
|                 merchant_id, | ||||
|                 connector_name, | ||||
|             ) | ||||
|             .await | ||||
|             .map_err(Into::into) | ||||
|             .into_report() | ||||
|         }; | ||||
|         let mca_list = find_call().await?; | ||||
|         match mca_list.len().cmp(&1) { | ||||
|             Ordering::Less => { | ||||
|                 Err(errors::StorageError::ValueNotFound("MerchantConnectorAccount".into()).into()) | ||||
|                     .attach_printable(format!( | ||||
|                         "No records found for {} and {}", | ||||
|                         merchant_id, connector_name | ||||
|                     )) | ||||
|             } | ||||
|             Ordering::Greater => Err(errors::StorageError::DatabaseError( | ||||
|                 storage_errors::DatabaseError::Others.into(), | ||||
|             )) | ||||
|             .into_report() | ||||
|             .attach_printable(format!( | ||||
|                 "Found multiple records for {} and {}", | ||||
|                 merchant_id, connector_name | ||||
|             )), | ||||
|             Ordering::Equal => match mca_list.first() { | ||||
|                 Some(mca) => mca | ||||
|                     .to_owned() | ||||
|                     .convert(key_store.key.get_inner()) | ||||
|                     .await | ||||
|                     .change_context(errors::StorageError::DeserializationFailed), | ||||
|                 None => Err( | ||||
|                     errors::StorageError::ValueNotFound("MerchantConnectorAccount".into()).into(), | ||||
|                 ), | ||||
|             }, | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     async fn find_by_merchant_connector_account_merchant_id_merchant_connector_id( | ||||
|         &self, | ||||
|         merchant_id: &str, | ||||
| @ -377,7 +434,7 @@ impl MerchantConnectorAccountInterface for MockDb { | ||||
|             .await | ||||
|             .iter() | ||||
|             .find(|account| { | ||||
|                 account.merchant_id == merchant_id && account.connector_name == connector | ||||
|                 account.merchant_id == merchant_id && account.connector_label == connector | ||||
|             }) | ||||
|             .cloned() | ||||
|             .async_map(|account| async { | ||||
| @ -398,6 +455,51 @@ impl MerchantConnectorAccountInterface for MockDb { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     async fn find_merchant_connector_account_by_merchant_id_connector_name( | ||||
|         &self, | ||||
|         merchant_id: &str, | ||||
|         connector_name: &str, | ||||
|         key_store: &domain::MerchantKeyStore, | ||||
|     ) -> CustomResult<domain::MerchantConnectorAccount, errors::StorageError> { | ||||
|         let mca_list = self | ||||
|             .merchant_connector_accounts | ||||
|             .lock() | ||||
|             .await | ||||
|             .iter() | ||||
|             .filter(|account| { | ||||
|                 account.merchant_id == merchant_id && account.connector_name == connector_name | ||||
|             }) | ||||
|             .cloned() | ||||
|             .collect::<Vec<_>>(); | ||||
|         match mca_list.len().cmp(&1) { | ||||
|             Ordering::Less => { | ||||
|                 Err(errors::StorageError::ValueNotFound("MerchantConnectorAccount".into()).into()) | ||||
|                     .attach_printable(format!( | ||||
|                         "No records found for {} and {}", | ||||
|                         merchant_id, connector_name | ||||
|                     )) | ||||
|             } | ||||
|             Ordering::Greater => Err(errors::StorageError::DatabaseError( | ||||
|                 storage_errors::DatabaseError::Others.into(), | ||||
|             )) | ||||
|             .into_report() | ||||
|             .attach_printable(format!( | ||||
|                 "Found multiple records for {} and {}", | ||||
|                 merchant_id, connector_name | ||||
|             )), | ||||
|             Ordering::Equal => match mca_list.first() { | ||||
|                 Some(mca) => mca | ||||
|                     .to_owned() | ||||
|                     .convert(key_store.key.get_inner()) | ||||
|                     .await | ||||
|                     .change_context(errors::StorageError::DeserializationFailed), | ||||
|                 None => Err( | ||||
|                     errors::StorageError::ValueNotFound("MerchantConnectorAccount".into()).into(), | ||||
|                 ), | ||||
|             }, | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     async fn find_by_merchant_connector_account_merchant_id_merchant_connector_id( | ||||
|         &self, | ||||
|         merchant_id: &str, | ||||
|  | ||||
| @ -410,7 +410,7 @@ impl Webhooks { | ||||
|         web::scope("/webhooks") | ||||
|             .app_data(web::Data::new(config)) | ||||
|             .service( | ||||
|                 web::resource("/{merchant_id}/{connector_label}") | ||||
|                 web::resource("/{merchant_id}/{connector_name}") | ||||
|                     .route( | ||||
|                         web::post().to(receive_incoming_webhook::<webhook_type::OutgoingWebhook>), | ||||
|                     ) | ||||
|  | ||||
| @ -15,7 +15,7 @@ pub async fn receive_incoming_webhook<W: types::OutgoingWebhookType>( | ||||
|     path: web::Path<(String, String)>, | ||||
| ) -> impl Responder { | ||||
|     let flow = Flow::IncomingWebhookReceive; | ||||
|     let (merchant_id, connector_label) = path.into_inner(); | ||||
|     let (merchant_id, connector_name) = path.into_inner(); | ||||
|  | ||||
|     api::server_wrap( | ||||
|         flow, | ||||
| @ -28,7 +28,7 @@ pub async fn receive_incoming_webhook<W: types::OutgoingWebhookType>( | ||||
|                 &req, | ||||
|                 auth.merchant_account, | ||||
|                 auth.key_store, | ||||
|                 &connector_label, | ||||
|                 &connector_name, | ||||
|                 body, | ||||
|             ) | ||||
|         }, | ||||
|  | ||||
| @ -11,7 +11,7 @@ use super::ConnectorCommon; | ||||
| use crate::{ | ||||
|     core::errors::{self, CustomResult}, | ||||
|     db::StorageInterface, | ||||
|     services, | ||||
|     logger, services, | ||||
|     types::domain, | ||||
|     utils::crypto, | ||||
| }; | ||||
| @ -79,32 +79,28 @@ pub trait IncomingWebhook: ConnectorCommon + Sync { | ||||
|         &self, | ||||
|         db: &dyn StorageInterface, | ||||
|         merchant_id: &str, | ||||
|         connector_label: &str, | ||||
|         connector_name: &str, | ||||
|         key_store: &domain::MerchantKeyStore, | ||||
|     ) -> CustomResult<Vec<u8>, errors::ConnectorError> { | ||||
|         let debug_suffix = format!( | ||||
|             "For merchant_id: {}, and connector_label: {}", | ||||
|             merchant_id, connector_label | ||||
|             "For merchant_id: {}, and connector_name: {}", | ||||
|             merchant_id, connector_name | ||||
|         ); | ||||
|         let merchant_connector_webhook_details = db | ||||
|             .find_merchant_connector_account_by_merchant_id_connector_label( | ||||
|         let default_secret = "default_secret".to_string(); | ||||
|         let merchant_connector_account_result = db | ||||
|             .find_merchant_connector_account_by_merchant_id_connector_name( | ||||
|                 merchant_id, | ||||
|                 connector_label, | ||||
|                 connector_name, | ||||
|                 key_store, | ||||
|             ) | ||||
|             .await | ||||
|             .change_context(errors::ConnectorError::WebhookSourceVerificationFailed) | ||||
|             .attach_printable_lazy(|| { | ||||
|                 format!( | ||||
|                     "Fetch merchant_webhook_secret from MCA table failed {}", | ||||
|                     debug_suffix | ||||
|                 ) | ||||
|             })? | ||||
|             .connector_webhook_details; | ||||
|             .await; | ||||
|  | ||||
|         let merchant_secret = match merchant_connector_webhook_details { | ||||
|         let merchant_secret = match merchant_connector_account_result { | ||||
|             Ok(mca) => match mca.connector_webhook_details { | ||||
|                 Some(merchant_connector_webhook_details) => merchant_connector_webhook_details | ||||
|                 .parse_value::<MerchantConnectorWebhookDetails>("MerchantConnectorWebhookDetails") | ||||
|                     .parse_value::<MerchantConnectorWebhookDetails>( | ||||
|                         "MerchantConnectorWebhookDetails", | ||||
|                     ) | ||||
|                     .change_context_lazy(|| errors::ConnectorError::WebhookSourceVerificationFailed) | ||||
|                     .attach_printable_lazy(|| { | ||||
|                         format!( | ||||
| @ -114,8 +110,18 @@ pub trait IncomingWebhook: ConnectorCommon + Sync { | ||||
|                     })? | ||||
|                     .merchant_secret | ||||
|                     .expose(), | ||||
|             None => "default_secret".to_string(), | ||||
|                 None => default_secret, | ||||
|             }, | ||||
|             Err(err) => { | ||||
|                 logger::error!( | ||||
|                     "Failed to fetch merchant_secret for source verification {}", | ||||
|                     debug_suffix | ||||
|                 ); | ||||
|                 logger::error!("DB error = {:?}", err); | ||||
|                 default_secret | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         //need to fetch merchant secret from config table with caching in future for enhanced performance | ||||
|  | ||||
|         //If merchant has not set the secret for webhook source verification, "default_secret" is returned. | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Hrithikesh
					Hrithikesh