mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-27 19:46:48 +08:00
refactor(webhooks): check event type not supported before checking for profile_id (#3543)
This commit is contained in:
@ -984,16 +984,15 @@ pub async fn webhooks_core<W: types::OutgoingWebhookType, Ctx: PaymentMethodRetr
|
||||
// Fetch the merchant connector account to get the webhooks source secret
|
||||
// `webhooks source secret` is a secret shared between the merchant and connector
|
||||
// This is used for source verification and webhooks integrity
|
||||
let (merchant_connector_account, connector) = fetch_mca_and_connector(
|
||||
let (merchant_connector_account, connector) = fetch_optional_mca_and_connector(
|
||||
&state,
|
||||
&merchant_account,
|
||||
connector_name_or_mca_id,
|
||||
&key_store,
|
||||
&request_details,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let connector_name = merchant_connector_account.clone().connector_name;
|
||||
let connector_name = connector.connector_name.to_string();
|
||||
|
||||
let connector = connector.connector;
|
||||
|
||||
@ -1090,6 +1089,20 @@ pub async fn webhooks_core<W: types::OutgoingWebhookType, Ctx: PaymentMethodRetr
|
||||
})?;
|
||||
let connectors_with_source_verification_call = &state.conf.webhook_source_verification_call;
|
||||
|
||||
let merchant_connector_account = match merchant_connector_account {
|
||||
Some(merchant_connector_account) => merchant_connector_account,
|
||||
None => {
|
||||
helper_utils::get_mca_from_object_reference_id(
|
||||
&*state.clone().store,
|
||||
object_ref_id.clone(),
|
||||
&merchant_account,
|
||||
&connector_name,
|
||||
&key_store,
|
||||
)
|
||||
.await?
|
||||
}
|
||||
};
|
||||
|
||||
let source_verified = if connectors_with_source_verification_call
|
||||
.connectors_with_webhook_source_verification_call
|
||||
.contains(&connector_enum)
|
||||
@ -1311,14 +1324,17 @@ pub async fn get_payment_id(
|
||||
.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
|
||||
}
|
||||
|
||||
async fn fetch_mca_and_connector(
|
||||
/// This function fetches the merchant connector account ( if the url used is /{merchant_connector_id})
|
||||
/// if merchant connector id is not passed in the request, then this will return None for mca
|
||||
async fn fetch_optional_mca_and_connector(
|
||||
state: &AppState,
|
||||
merchant_account: &domain::MerchantAccount,
|
||||
connector_name_or_mca_id: &str,
|
||||
key_store: &domain::MerchantKeyStore,
|
||||
request_details: &api::IncomingWebhookRequestDetails<'_>,
|
||||
) -> CustomResult<(domain::MerchantConnectorAccount, api::ConnectorData), errors::ApiErrorResponse>
|
||||
{
|
||||
) -> CustomResult<
|
||||
(Option<domain::MerchantConnectorAccount>, api::ConnectorData),
|
||||
errors::ApiErrorResponse,
|
||||
> {
|
||||
let db = &state.store;
|
||||
if connector_name_or_mca_id.starts_with("mca_") {
|
||||
let mca = db
|
||||
@ -1346,7 +1362,7 @@ async fn fetch_mca_and_connector(
|
||||
})
|
||||
.attach_printable("Failed construction of ConnectorData")?;
|
||||
|
||||
Ok((mca, connector))
|
||||
Ok((Some(mca), connector))
|
||||
} else {
|
||||
// Merchant connector account is already being queried, it is safe to set connector id as None
|
||||
let connector = api::ConnectorData::get_connector_by_name(
|
||||
@ -1360,38 +1376,6 @@ async fn fetch_mca_and_connector(
|
||||
})
|
||||
.attach_printable("Failed construction of ConnectorData")?;
|
||||
|
||||
let object_ref_id = connector
|
||||
.connector
|
||||
.get_webhook_object_reference_id(request_details)
|
||||
.switch()
|
||||
.attach_printable("Could not find object reference id in incoming webhook body")?;
|
||||
|
||||
let profile_id = helper_utils::get_profile_id_using_object_reference_id(
|
||||
&*state.store,
|
||||
object_ref_id,
|
||||
merchant_account,
|
||||
connector_name_or_mca_id,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InvalidDataValue {
|
||||
field_name: "object reference id",
|
||||
})
|
||||
.attach_printable("Could not find profile id from object reference id")?;
|
||||
|
||||
let mca = db
|
||||
.find_merchant_connector_account_by_profile_id_connector_name(
|
||||
&profile_id,
|
||||
connector_name_or_mca_id,
|
||||
key_store,
|
||||
)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::MerchantConnectorAccountNotFound {
|
||||
id: format!(
|
||||
"profile_id {profile_id} and connector name {connector_name_or_mca_id}"
|
||||
),
|
||||
})
|
||||
.attach_printable("error while fetching merchant_connector_account from profile_id")?;
|
||||
|
||||
Ok((mca, connector))
|
||||
Ok((None, connector))
|
||||
}
|
||||
}
|
||||
|
||||
@ -326,14 +326,26 @@ pub async fn find_payment_intent_from_mandate_id_type(
|
||||
.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
|
||||
}
|
||||
|
||||
pub async fn get_profile_id_using_object_reference_id(
|
||||
pub async fn get_mca_from_object_reference_id(
|
||||
db: &dyn StorageInterface,
|
||||
object_reference_id: webhooks::ObjectReferenceId,
|
||||
merchant_account: &domain::MerchantAccount,
|
||||
connector_name: &str,
|
||||
) -> CustomResult<String, errors::ApiErrorResponse> {
|
||||
key_store: &domain::MerchantKeyStore,
|
||||
) -> CustomResult<domain::MerchantConnectorAccount, errors::ApiErrorResponse> {
|
||||
let merchant_id = merchant_account.merchant_id.clone();
|
||||
|
||||
match merchant_account.default_profile.as_ref() {
|
||||
Some(profile_id) => Ok(profile_id.clone()),
|
||||
Some(profile_id) => db
|
||||
.find_merchant_connector_account_by_profile_id_connector_name(
|
||||
profile_id,
|
||||
connector_name,
|
||||
key_store,
|
||||
)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::MerchantConnectorAccountNotFound {
|
||||
id: format!("profile_id {profile_id} and connector_name {connector_name}"),
|
||||
}),
|
||||
_ => {
|
||||
let payment_intent = match object_reference_id {
|
||||
webhooks::ObjectReferenceId::PaymentId(payment_id_type) => {
|
||||
@ -355,19 +367,56 @@ pub async fn get_profile_id_using_object_reference_id(
|
||||
}
|
||||
};
|
||||
|
||||
let profile_id = utils::get_profile_id_from_business_details(
|
||||
payment_intent.business_country,
|
||||
payment_intent.business_label.as_ref(),
|
||||
merchant_account,
|
||||
payment_intent.profile_id.as_ref(),
|
||||
db,
|
||||
false,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("profile_id is not set in payment_intent")?;
|
||||
let payment_attempt = db
|
||||
.find_payment_attempt_by_attempt_id_merchant_id(
|
||||
&payment_intent.active_attempt.get_id(),
|
||||
&merchant_id,
|
||||
merchant_account.storage_scheme,
|
||||
)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
|
||||
|
||||
Ok(profile_id)
|
||||
match payment_attempt.merchant_connector_id {
|
||||
Some(merchant_connector_id) => db
|
||||
.find_by_merchant_connector_account_merchant_id_merchant_connector_id(
|
||||
&merchant_id,
|
||||
&merchant_connector_id,
|
||||
key_store,
|
||||
)
|
||||
.await
|
||||
.to_not_found_response(
|
||||
errors::ApiErrorResponse::MerchantConnectorAccountNotFound {
|
||||
id: merchant_connector_id,
|
||||
},
|
||||
),
|
||||
None => {
|
||||
let profile_id = utils::get_profile_id_from_business_details(
|
||||
payment_intent.business_country,
|
||||
payment_intent.business_label.as_ref(),
|
||||
merchant_account,
|
||||
payment_intent.profile_id.as_ref(),
|
||||
db,
|
||||
false,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("profile_id is not set in payment_intent")?;
|
||||
|
||||
db.find_merchant_connector_account_by_profile_id_connector_name(
|
||||
&profile_id,
|
||||
connector_name,
|
||||
key_store,
|
||||
)
|
||||
.await
|
||||
.to_not_found_response(
|
||||
errors::ApiErrorResponse::MerchantConnectorAccountNotFound {
|
||||
id: format!(
|
||||
"profile_id {profile_id} and connector_name {connector_name}"
|
||||
),
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user