mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-28 20:23:43 +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
|
// Fetch the merchant connector account to get the webhooks source secret
|
||||||
// `webhooks source secret` is a secret shared between the merchant and connector
|
// `webhooks source secret` is a secret shared between the merchant and connector
|
||||||
// This is used for source verification and webhooks integrity
|
// 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,
|
&state,
|
||||||
&merchant_account,
|
&merchant_account,
|
||||||
connector_name_or_mca_id,
|
connector_name_or_mca_id,
|
||||||
&key_store,
|
&key_store,
|
||||||
&request_details,
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let connector_name = merchant_connector_account.clone().connector_name;
|
let connector_name = connector.connector_name.to_string();
|
||||||
|
|
||||||
let connector = connector.connector;
|
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 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
|
let source_verified = if connectors_with_source_verification_call
|
||||||
.connectors_with_webhook_source_verification_call
|
.connectors_with_webhook_source_verification_call
|
||||||
.contains(&connector_enum)
|
.contains(&connector_enum)
|
||||||
@ -1311,14 +1324,17 @@ pub async fn get_payment_id(
|
|||||||
.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
|
.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,
|
state: &AppState,
|
||||||
merchant_account: &domain::MerchantAccount,
|
merchant_account: &domain::MerchantAccount,
|
||||||
connector_name_or_mca_id: &str,
|
connector_name_or_mca_id: &str,
|
||||||
key_store: &domain::MerchantKeyStore,
|
key_store: &domain::MerchantKeyStore,
|
||||||
request_details: &api::IncomingWebhookRequestDetails<'_>,
|
) -> CustomResult<
|
||||||
) -> CustomResult<(domain::MerchantConnectorAccount, api::ConnectorData), errors::ApiErrorResponse>
|
(Option<domain::MerchantConnectorAccount>, api::ConnectorData),
|
||||||
{
|
errors::ApiErrorResponse,
|
||||||
|
> {
|
||||||
let db = &state.store;
|
let db = &state.store;
|
||||||
if connector_name_or_mca_id.starts_with("mca_") {
|
if connector_name_or_mca_id.starts_with("mca_") {
|
||||||
let mca = db
|
let mca = db
|
||||||
@ -1346,7 +1362,7 @@ async fn fetch_mca_and_connector(
|
|||||||
})
|
})
|
||||||
.attach_printable("Failed construction of ConnectorData")?;
|
.attach_printable("Failed construction of ConnectorData")?;
|
||||||
|
|
||||||
Ok((mca, connector))
|
Ok((Some(mca), connector))
|
||||||
} else {
|
} else {
|
||||||
// Merchant connector account is already being queried, it is safe to set connector id as None
|
// Merchant connector account is already being queried, it is safe to set connector id as None
|
||||||
let connector = api::ConnectorData::get_connector_by_name(
|
let connector = api::ConnectorData::get_connector_by_name(
|
||||||
@ -1360,38 +1376,6 @@ async fn fetch_mca_and_connector(
|
|||||||
})
|
})
|
||||||
.attach_printable("Failed construction of ConnectorData")?;
|
.attach_printable("Failed construction of ConnectorData")?;
|
||||||
|
|
||||||
let object_ref_id = connector
|
Ok((None, 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))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -326,14 +326,26 @@ pub async fn find_payment_intent_from_mandate_id_type(
|
|||||||
.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
|
.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,
|
db: &dyn StorageInterface,
|
||||||
object_reference_id: webhooks::ObjectReferenceId,
|
object_reference_id: webhooks::ObjectReferenceId,
|
||||||
merchant_account: &domain::MerchantAccount,
|
merchant_account: &domain::MerchantAccount,
|
||||||
connector_name: &str,
|
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() {
|
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 {
|
let payment_intent = match object_reference_id {
|
||||||
webhooks::ObjectReferenceId::PaymentId(payment_id_type) => {
|
webhooks::ObjectReferenceId::PaymentId(payment_id_type) => {
|
||||||
@ -355,6 +367,29 @@ pub async fn get_profile_id_using_object_reference_id(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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)?;
|
||||||
|
|
||||||
|
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(
|
let profile_id = utils::get_profile_id_from_business_details(
|
||||||
payment_intent.business_country,
|
payment_intent.business_country,
|
||||||
payment_intent.business_label.as_ref(),
|
payment_intent.business_label.as_ref(),
|
||||||
@ -367,7 +402,21 @@ pub async fn get_profile_id_using_object_reference_id(
|
|||||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||||
.attach_printable("profile_id is not set in payment_intent")?;
|
.attach_printable("profile_id is not set in payment_intent")?;
|
||||||
|
|
||||||
Ok(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}"
|
||||||
|
),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user