mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-02 12:06:56 +08:00
refactor(core): use business_profile to read merchant configs (#2729)
This commit is contained in:
@ -1,4 +1,7 @@
|
||||
use api_models::{admin as admin_types, enums as api_enums};
|
||||
use api_models::{
|
||||
admin::{self as admin_types},
|
||||
enums as api_enums,
|
||||
};
|
||||
use common_utils::{
|
||||
crypto::{generate_cryptographically_secure_random_string, OptionalSecretValue},
|
||||
date_time,
|
||||
@ -6,6 +9,7 @@ use common_utils::{
|
||||
pii,
|
||||
};
|
||||
use error_stack::{report, FutureExt, ResultExt};
|
||||
use futures::future::try_join_all;
|
||||
use masking::{PeekInterface, Secret};
|
||||
use uuid::Uuid;
|
||||
|
||||
@ -379,6 +383,66 @@ pub async fn create_business_profile_from_business_labels(
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// For backwards compatibility
|
||||
/// If any of the fields of merchant account are updated, then update these fields in business profiles
|
||||
pub async fn update_business_profile_cascade(
|
||||
state: AppState,
|
||||
merchant_account_update: api::MerchantAccountUpdate,
|
||||
merchant_id: String,
|
||||
) -> RouterResult<()> {
|
||||
if merchant_account_update.return_url.is_some()
|
||||
|| merchant_account_update.webhook_details.is_some()
|
||||
|| merchant_account_update
|
||||
.enable_payment_response_hash
|
||||
.is_some()
|
||||
|| merchant_account_update
|
||||
.redirect_to_merchant_with_http_post
|
||||
.is_some()
|
||||
{
|
||||
// Update these fields in all the business profiles
|
||||
let business_profiles = state
|
||||
.store
|
||||
.list_business_profile_by_merchant_id(&merchant_id)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::BusinessProfileNotFound {
|
||||
id: merchant_id.to_string(),
|
||||
})?;
|
||||
|
||||
let business_profile_update = admin_types::BusinessProfileUpdate {
|
||||
profile_name: None,
|
||||
return_url: merchant_account_update.return_url,
|
||||
enable_payment_response_hash: merchant_account_update.enable_payment_response_hash,
|
||||
payment_response_hash_key: merchant_account_update.payment_response_hash_key,
|
||||
redirect_to_merchant_with_http_post: merchant_account_update
|
||||
.redirect_to_merchant_with_http_post,
|
||||
webhook_details: merchant_account_update.webhook_details,
|
||||
metadata: None,
|
||||
routing_algorithm: None,
|
||||
intent_fulfillment_time: None,
|
||||
frm_routing_algorithm: None,
|
||||
payout_routing_algorithm: None,
|
||||
applepay_verified_domains: None,
|
||||
};
|
||||
|
||||
let update_futures = business_profiles.iter().map(|business_profile| async {
|
||||
let profile_id = &business_profile.profile_id;
|
||||
|
||||
update_business_profile(
|
||||
state.clone(),
|
||||
profile_id,
|
||||
&merchant_id,
|
||||
business_profile_update.clone(),
|
||||
)
|
||||
.await
|
||||
});
|
||||
|
||||
try_join_all(update_futures).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn merchant_account_update(
|
||||
state: AppState,
|
||||
merchant_id: &String,
|
||||
@ -431,6 +495,7 @@ pub async fn merchant_account_update(
|
||||
// In order to support backwards compatibility, if a business_labels are passed in the update
|
||||
// call, then create new business_profiles with the profile_name as business_label
|
||||
req.primary_business_details
|
||||
.clone()
|
||||
.async_map(|primary_business_details| async {
|
||||
let _ = create_business_profile_from_business_labels(
|
||||
db,
|
||||
@ -444,10 +509,10 @@ pub async fn merchant_account_update(
|
||||
|
||||
let key = key_store.key.get_inner().peek();
|
||||
|
||||
let business_profile_id_update = if let Some(profile_id) = req.default_profile {
|
||||
let business_profile_id_update = if let Some(ref profile_id) = req.default_profile {
|
||||
if !profile_id.is_empty_after_trim() {
|
||||
// Validate whether profile_id passed in request is valid and is linked to the merchant
|
||||
core_utils::validate_and_get_business_profile(db, Some(&profile_id), merchant_id)
|
||||
core_utils::validate_and_get_business_profile(db, Some(profile_id), merchant_id)
|
||||
.await?
|
||||
.map(|business_profile| Some(business_profile.profile_id))
|
||||
} else {
|
||||
@ -458,6 +523,9 @@ pub async fn merchant_account_update(
|
||||
None
|
||||
};
|
||||
|
||||
// Update the business profile, This is for backwards compatibility
|
||||
update_business_profile_cascade(state.clone(), req.clone(), merchant_id.to_string()).await?;
|
||||
|
||||
let updated_merchant_account = storage::MerchantAccountUpdate::Update {
|
||||
merchant_name: req
|
||||
.merchant_name
|
||||
|
||||
@ -345,7 +345,7 @@ pub trait PaymentRedirectFlow<Ctx: PaymentMethodRetrieve>: Sync {
|
||||
fn generate_response(
|
||||
&self,
|
||||
payments_response: api_models::payments::PaymentsResponse,
|
||||
merchant_account: router_types::domain::MerchantAccount,
|
||||
business_profile: diesel_models::business_profile::BusinessProfile,
|
||||
payment_id: String,
|
||||
connector: String,
|
||||
) -> RouterResult<api::RedirectionResponse>;
|
||||
@ -418,8 +418,21 @@ pub trait PaymentRedirectFlow<Ctx: PaymentMethodRetrieve>: Sync {
|
||||
.attach_printable("Failed to get the response in json"),
|
||||
}?;
|
||||
|
||||
let profile_id = payments_response
|
||||
.profile_id
|
||||
.as_ref()
|
||||
.get_required_value("profile_id")?;
|
||||
|
||||
let business_profile = state
|
||||
.store
|
||||
.find_business_profile_by_profile_id(profile_id)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::BusinessProfileNotFound {
|
||||
id: profile_id.to_string(),
|
||||
})?;
|
||||
|
||||
let result =
|
||||
self.generate_response(payments_response, merchant_account, resource_id, connector)?;
|
||||
self.generate_response(payments_response, business_profile, resource_id, connector)?;
|
||||
|
||||
Ok(services::ApplicationResponse::JsonForRedirection(result))
|
||||
}
|
||||
@ -469,7 +482,7 @@ impl<Ctx: PaymentMethodRetrieve> PaymentRedirectFlow<Ctx> for PaymentRedirectCom
|
||||
fn generate_response(
|
||||
&self,
|
||||
payments_response: api_models::payments::PaymentsResponse,
|
||||
merchant_account: router_types::domain::MerchantAccount,
|
||||
business_profile: diesel_models::business_profile::BusinessProfile,
|
||||
payment_id: String,
|
||||
connector: String,
|
||||
) -> RouterResult<api::RedirectionResponse> {
|
||||
@ -506,7 +519,7 @@ impl<Ctx: PaymentMethodRetrieve> PaymentRedirectFlow<Ctx> for PaymentRedirectCom
|
||||
| api_models::enums::IntentStatus::Failed
|
||||
| api_models::enums::IntentStatus::Cancelled | api_models::enums::IntentStatus::RequiresCapture| api_models::enums::IntentStatus::Processing=> helpers::get_handle_response_url(
|
||||
payment_id,
|
||||
&merchant_account,
|
||||
&business_profile,
|
||||
payments_response,
|
||||
connector,
|
||||
),
|
||||
@ -560,13 +573,13 @@ impl<Ctx: PaymentMethodRetrieve> PaymentRedirectFlow<Ctx> for PaymentRedirectSyn
|
||||
fn generate_response(
|
||||
&self,
|
||||
payments_response: api_models::payments::PaymentsResponse,
|
||||
merchant_account: router_types::domain::MerchantAccount,
|
||||
business_profile: diesel_models::business_profile::BusinessProfile,
|
||||
payment_id: String,
|
||||
connector: String,
|
||||
) -> RouterResult<api::RedirectionResponse> {
|
||||
helpers::get_handle_response_url(
|
||||
payment_id,
|
||||
&merchant_account,
|
||||
&business_profile,
|
||||
payments_response,
|
||||
connector,
|
||||
)
|
||||
|
||||
@ -1891,7 +1891,7 @@ pub(super) fn validate_payment_list_request_for_joins(
|
||||
|
||||
pub fn get_handle_response_url(
|
||||
payment_id: String,
|
||||
merchant_account: &domain::MerchantAccount,
|
||||
business_profile: &diesel_models::business_profile::BusinessProfile,
|
||||
response: api::PaymentsResponse,
|
||||
connector: String,
|
||||
) -> RouterResult<api::RedirectionResponse> {
|
||||
@ -1900,7 +1900,7 @@ pub fn get_handle_response_url(
|
||||
let redirection_response = make_pg_redirect_response(payment_id, &response, connector);
|
||||
|
||||
let return_url = make_merchant_url_with_response(
|
||||
merchant_account,
|
||||
business_profile,
|
||||
redirection_response,
|
||||
payments_return_url,
|
||||
response.client_secret.as_ref(),
|
||||
@ -1908,11 +1908,11 @@ pub fn get_handle_response_url(
|
||||
)
|
||||
.attach_printable("Failed to make merchant url with response")?;
|
||||
|
||||
make_url_with_signature(&return_url, merchant_account)
|
||||
make_url_with_signature(&return_url, business_profile)
|
||||
}
|
||||
|
||||
pub fn make_merchant_url_with_response(
|
||||
merchant_account: &domain::MerchantAccount,
|
||||
business_profile: &diesel_models::business_profile::BusinessProfile,
|
||||
redirection_response: api::PgRedirectResponse,
|
||||
request_return_url: Option<&String>,
|
||||
client_secret: Option<&masking::Secret<String>>,
|
||||
@ -1920,7 +1920,7 @@ pub fn make_merchant_url_with_response(
|
||||
) -> RouterResult<String> {
|
||||
// take return url if provided in the request else use merchant return url
|
||||
let url = request_return_url
|
||||
.or(merchant_account.return_url.as_ref())
|
||||
.or(business_profile.return_url.as_ref())
|
||||
.get_required_value("return_url")?;
|
||||
|
||||
let status_check = redirection_response.status;
|
||||
@ -1930,7 +1930,7 @@ pub fn make_merchant_url_with_response(
|
||||
.into_report()
|
||||
.attach_printable("Expected client secret to be `Some`")?;
|
||||
|
||||
let merchant_url_with_response = if merchant_account.redirect_to_merchant_with_http_post {
|
||||
let merchant_url_with_response = if business_profile.redirect_to_merchant_with_http_post {
|
||||
url::Url::parse_with_params(
|
||||
url,
|
||||
&[
|
||||
@ -2024,7 +2024,7 @@ pub fn make_pg_redirect_response(
|
||||
|
||||
pub fn make_url_with_signature(
|
||||
redirect_url: &str,
|
||||
merchant_account: &domain::MerchantAccount,
|
||||
business_profile: &diesel_models::business_profile::BusinessProfile,
|
||||
) -> RouterResult<api::RedirectionResponse> {
|
||||
let mut url = url::Url::parse(redirect_url)
|
||||
.into_report()
|
||||
@ -2034,8 +2034,8 @@ pub fn make_url_with_signature(
|
||||
let mut base_url = url.clone();
|
||||
base_url.query_pairs_mut().clear();
|
||||
|
||||
let url = if merchant_account.enable_payment_response_hash {
|
||||
let key = merchant_account
|
||||
let url = if business_profile.enable_payment_response_hash {
|
||||
let key = business_profile
|
||||
.payment_response_hash_key
|
||||
.as_ref()
|
||||
.get_required_value("payment_response_hash_key")?;
|
||||
@ -2063,7 +2063,7 @@ pub fn make_url_with_signature(
|
||||
return_url: base_url.to_string(),
|
||||
params: parameters,
|
||||
return_url_with_query_params: url.to_string(),
|
||||
http_method: if merchant_account.redirect_to_merchant_with_http_post {
|
||||
http_method: if business_profile.redirect_to_merchant_with_http_post {
|
||||
services::Method::Post.to_string()
|
||||
} else {
|
||||
services::Method::Get.to_string()
|
||||
|
||||
@ -46,6 +46,7 @@ pub async fn payments_incoming_webhook_flow<
|
||||
>(
|
||||
state: AppState,
|
||||
merchant_account: domain::MerchantAccount,
|
||||
business_profile: diesel_models::business_profile::BusinessProfile,
|
||||
key_store: domain::MerchantKeyStore,
|
||||
webhook_details: api::IncomingWebhookDetails,
|
||||
source_verified: bool,
|
||||
@ -156,6 +157,7 @@ pub async fn payments_incoming_webhook_flow<
|
||||
create_event_and_trigger_outgoing_webhook::<W>(
|
||||
state,
|
||||
merchant_account,
|
||||
business_profile,
|
||||
outgoing_event_type,
|
||||
enums::EventClass::Payments,
|
||||
None,
|
||||
@ -178,9 +180,11 @@ pub async fn payments_incoming_webhook_flow<
|
||||
}
|
||||
|
||||
#[instrument(skip_all)]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn refunds_incoming_webhook_flow<W: types::OutgoingWebhookType>(
|
||||
state: AppState,
|
||||
merchant_account: domain::MerchantAccount,
|
||||
business_profile: diesel_models::business_profile::BusinessProfile,
|
||||
key_store: domain::MerchantKeyStore,
|
||||
webhook_details: api::IncomingWebhookDetails,
|
||||
connector_name: &str,
|
||||
@ -269,6 +273,7 @@ pub async fn refunds_incoming_webhook_flow<W: types::OutgoingWebhookType>(
|
||||
create_event_and_trigger_outgoing_webhook::<W>(
|
||||
state,
|
||||
merchant_account,
|
||||
business_profile,
|
||||
outgoing_event_type,
|
||||
enums::EventClass::Refunds,
|
||||
None,
|
||||
@ -404,6 +409,7 @@ pub async fn get_or_update_dispute_object(
|
||||
pub async fn mandates_incoming_webhook_flow<W: types::OutgoingWebhookType>(
|
||||
state: AppState,
|
||||
merchant_account: domain::MerchantAccount,
|
||||
business_profile: diesel_models::business_profile::BusinessProfile,
|
||||
webhook_details: api::IncomingWebhookDetails,
|
||||
source_verified: bool,
|
||||
event_type: api_models::webhooks::IncomingWebhookEvent,
|
||||
@ -455,6 +461,7 @@ pub async fn mandates_incoming_webhook_flow<W: types::OutgoingWebhookType>(
|
||||
create_event_and_trigger_outgoing_webhook::<W>(
|
||||
state,
|
||||
merchant_account,
|
||||
business_profile,
|
||||
outgoing_event_type,
|
||||
enums::EventClass::Mandates,
|
||||
None,
|
||||
@ -474,10 +481,12 @@ pub async fn mandates_incoming_webhook_flow<W: types::OutgoingWebhookType>(
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn disputes_incoming_webhook_flow<W: types::OutgoingWebhookType>(
|
||||
state: AppState,
|
||||
merchant_account: domain::MerchantAccount,
|
||||
business_profile: diesel_models::business_profile::BusinessProfile,
|
||||
webhook_details: api::IncomingWebhookDetails,
|
||||
source_verified: bool,
|
||||
connector: &(dyn api::Connector + Sync),
|
||||
@ -518,6 +527,7 @@ pub async fn disputes_incoming_webhook_flow<W: types::OutgoingWebhookType>(
|
||||
create_event_and_trigger_outgoing_webhook::<W>(
|
||||
state,
|
||||
merchant_account,
|
||||
business_profile,
|
||||
event_type,
|
||||
enums::EventClass::Disputes,
|
||||
None,
|
||||
@ -541,6 +551,7 @@ pub async fn disputes_incoming_webhook_flow<W: types::OutgoingWebhookType>(
|
||||
async fn bank_transfer_webhook_flow<W: types::OutgoingWebhookType, Ctx: PaymentMethodRetrieve>(
|
||||
state: AppState,
|
||||
merchant_account: domain::MerchantAccount,
|
||||
business_profile: diesel_models::business_profile::BusinessProfile,
|
||||
key_store: domain::MerchantKeyStore,
|
||||
webhook_details: api::IncomingWebhookDetails,
|
||||
source_verified: bool,
|
||||
@ -594,6 +605,7 @@ async fn bank_transfer_webhook_flow<W: types::OutgoingWebhookType, Ctx: PaymentM
|
||||
create_event_and_trigger_outgoing_webhook::<W>(
|
||||
state,
|
||||
merchant_account,
|
||||
business_profile,
|
||||
outgoing_event_type,
|
||||
enums::EventClass::Payments,
|
||||
None,
|
||||
@ -618,6 +630,7 @@ async fn bank_transfer_webhook_flow<W: types::OutgoingWebhookType, Ctx: PaymentM
|
||||
pub async fn create_event_and_trigger_appropriate_outgoing_webhook(
|
||||
state: AppState,
|
||||
merchant_account: domain::MerchantAccount,
|
||||
business_profile: diesel_models::business_profile::BusinessProfile,
|
||||
event_type: enums::EventType,
|
||||
event_class: enums::EventClass,
|
||||
intent_reference_id: Option<String>,
|
||||
@ -631,6 +644,7 @@ pub async fn create_event_and_trigger_appropriate_outgoing_webhook(
|
||||
create_event_and_trigger_outgoing_webhook::<stripe_webhooks::StripeOutgoingWebhook>(
|
||||
state.clone(),
|
||||
merchant_account,
|
||||
business_profile,
|
||||
event_type,
|
||||
event_class,
|
||||
intent_reference_id,
|
||||
@ -644,6 +658,7 @@ pub async fn create_event_and_trigger_appropriate_outgoing_webhook(
|
||||
create_event_and_trigger_outgoing_webhook::<api_models::webhooks::OutgoingWebhook>(
|
||||
state.clone(),
|
||||
merchant_account,
|
||||
business_profile,
|
||||
event_type,
|
||||
event_class,
|
||||
intent_reference_id,
|
||||
@ -661,6 +676,7 @@ pub async fn create_event_and_trigger_appropriate_outgoing_webhook(
|
||||
pub async fn create_event_and_trigger_outgoing_webhook<W: types::OutgoingWebhookType>(
|
||||
state: AppState,
|
||||
merchant_account: domain::MerchantAccount,
|
||||
business_profile: diesel_models::business_profile::BusinessProfile,
|
||||
event_type: enums::EventType,
|
||||
event_class: enums::EventClass,
|
||||
intent_reference_id: Option<String>,
|
||||
@ -709,7 +725,7 @@ pub async fn create_event_and_trigger_outgoing_webhook<W: types::OutgoingWebhook
|
||||
// may have an actix arbiter
|
||||
tokio::spawn(async move {
|
||||
let result =
|
||||
trigger_webhook_to_merchant::<W>(merchant_account, outgoing_webhook, &state).await;
|
||||
trigger_webhook_to_merchant::<W>(business_profile, outgoing_webhook, &state).await;
|
||||
|
||||
if let Err(e) = result {
|
||||
logger::error!(?e);
|
||||
@ -721,11 +737,11 @@ pub async fn create_event_and_trigger_outgoing_webhook<W: types::OutgoingWebhook
|
||||
}
|
||||
|
||||
pub async fn trigger_webhook_to_merchant<W: types::OutgoingWebhookType>(
|
||||
merchant_account: domain::MerchantAccount,
|
||||
business_profile: diesel_models::business_profile::BusinessProfile,
|
||||
webhook: api::OutgoingWebhook,
|
||||
state: &AppState,
|
||||
) -> CustomResult<(), errors::WebhooksFlowError> {
|
||||
let webhook_details_json = merchant_account
|
||||
let webhook_details_json = business_profile
|
||||
.webhook_details
|
||||
.get_required_value("webhook_details")
|
||||
.change_context(errors::WebhooksFlowError::MerchantWebhookDetailsNotFound)?;
|
||||
@ -746,7 +762,7 @@ pub async fn trigger_webhook_to_merchant<W: types::OutgoingWebhookType>(
|
||||
let transformed_outgoing_webhook = W::from(webhook);
|
||||
|
||||
let outgoing_webhooks_signature = transformed_outgoing_webhook
|
||||
.get_outgoing_webhooks_signature(merchant_account.payment_response_hash_key.clone())?;
|
||||
.get_outgoing_webhooks_signature(business_profile.payment_response_hash_key.clone())?;
|
||||
|
||||
let transformed_outgoing_webhook_string = router_types::RequestBody::log_and_get_request_body(
|
||||
&transformed_outgoing_webhook,
|
||||
@ -782,7 +798,7 @@ pub async fn trigger_webhook_to_merchant<W: types::OutgoingWebhookType>(
|
||||
1,
|
||||
&[metrics::KeyValue::new(
|
||||
MERCHANT_ID,
|
||||
merchant_account.merchant_id.clone(),
|
||||
business_profile.merchant_id.clone(),
|
||||
)],
|
||||
);
|
||||
logger::debug!(outgoing_webhook_response=?response);
|
||||
@ -799,7 +815,7 @@ pub async fn trigger_webhook_to_merchant<W: types::OutgoingWebhookType>(
|
||||
1,
|
||||
&[metrics::KeyValue::new(
|
||||
MERCHANT_ID,
|
||||
merchant_account.merchant_id.clone(),
|
||||
business_profile.merchant_id.clone(),
|
||||
)],
|
||||
);
|
||||
let update_event = storage::EventUpdate::UpdateWebhookNotified {
|
||||
@ -816,7 +832,7 @@ pub async fn trigger_webhook_to_merchant<W: types::OutgoingWebhookType>(
|
||||
1,
|
||||
&[metrics::KeyValue::new(
|
||||
MERCHANT_ID,
|
||||
merchant_account.merchant_id.clone(),
|
||||
business_profile.merchant_id.clone(),
|
||||
)],
|
||||
);
|
||||
// [#217]: Schedule webhook for retry.
|
||||
@ -1048,10 +1064,26 @@ pub async fn webhooks_core<W: types::OutgoingWebhookType, Ctx: PaymentMethodRetr
|
||||
)?,
|
||||
};
|
||||
|
||||
let profile_id = merchant_connector_account
|
||||
.profile_id
|
||||
.as_ref()
|
||||
.get_required_value("profile_id")
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Could not find profile_id in merchant connector account")?;
|
||||
|
||||
let business_profile = state
|
||||
.store
|
||||
.find_business_profile_by_profile_id(profile_id)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::BusinessProfileNotFound {
|
||||
id: profile_id.to_string(),
|
||||
})?;
|
||||
|
||||
match flow_type {
|
||||
api::WebhookFlow::Payment => payments_incoming_webhook_flow::<W, Ctx>(
|
||||
state.clone(),
|
||||
merchant_account,
|
||||
business_profile,
|
||||
key_store,
|
||||
webhook_details,
|
||||
source_verified,
|
||||
@ -1062,6 +1094,7 @@ pub async fn webhooks_core<W: types::OutgoingWebhookType, Ctx: PaymentMethodRetr
|
||||
api::WebhookFlow::Refund => refunds_incoming_webhook_flow::<W>(
|
||||
state.clone(),
|
||||
merchant_account,
|
||||
business_profile,
|
||||
key_store,
|
||||
webhook_details,
|
||||
connector_name.as_str(),
|
||||
@ -1074,6 +1107,7 @@ pub async fn webhooks_core<W: types::OutgoingWebhookType, Ctx: PaymentMethodRetr
|
||||
api::WebhookFlow::Dispute => disputes_incoming_webhook_flow::<W>(
|
||||
state.clone(),
|
||||
merchant_account,
|
||||
business_profile,
|
||||
webhook_details,
|
||||
source_verified,
|
||||
*connector,
|
||||
@ -1086,6 +1120,7 @@ pub async fn webhooks_core<W: types::OutgoingWebhookType, Ctx: PaymentMethodRetr
|
||||
api::WebhookFlow::BankTransfer => bank_transfer_webhook_flow::<W, Ctx>(
|
||||
state.clone(),
|
||||
merchant_account,
|
||||
business_profile,
|
||||
key_store,
|
||||
webhook_details,
|
||||
source_verified,
|
||||
@ -1098,6 +1133,7 @@ pub async fn webhooks_core<W: types::OutgoingWebhookType, Ctx: PaymentMethodRetr
|
||||
api::WebhookFlow::Mandate => mandates_incoming_webhook_flow::<W>(
|
||||
state.clone(),
|
||||
merchant_account,
|
||||
business_profile,
|
||||
webhook_details,
|
||||
source_verified,
|
||||
event_type,
|
||||
|
||||
@ -699,6 +699,7 @@ impl ForeignTryFrom<enums::IntentStatus> for enums::EventType {
|
||||
|
||||
pub async fn trigger_payments_webhook<F, Req, Op>(
|
||||
merchant_account: domain::MerchantAccount,
|
||||
business_profile: diesel_models::business_profile::BusinessProfile,
|
||||
payment_data: crate::core::payments::PaymentData<F>,
|
||||
req: Option<Req>,
|
||||
customer: Option<domain::Customer>,
|
||||
@ -753,6 +754,7 @@ where
|
||||
webhooks_core::create_event_and_trigger_appropriate_outgoing_webhook(
|
||||
state.clone(),
|
||||
merchant_account,
|
||||
business_profile,
|
||||
event_type,
|
||||
diesel_models::enums::EventClass::Payments,
|
||||
None,
|
||||
|
||||
@ -149,10 +149,28 @@ impl ProcessTrackerWorkflow<AppState> for PaymentsSyncWorkflow {
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
|
||||
|
||||
let profile_id = payment_data
|
||||
.payment_intent
|
||||
.profile_id
|
||||
.as_ref()
|
||||
.get_required_value("profile_id")
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Could not find profile_id in payment intent")?;
|
||||
|
||||
let business_profile = db
|
||||
.find_business_profile_by_profile_id(profile_id)
|
||||
.await
|
||||
.to_not_found_response(
|
||||
errors::ApiErrorResponse::BusinessProfileNotFound {
|
||||
id: profile_id.to_string(),
|
||||
},
|
||||
)?;
|
||||
|
||||
// Trigger the outgoing webhook to notify the merchant about failed payment
|
||||
let operation = operations::PaymentStatus;
|
||||
utils::trigger_payments_webhook::<_, api_models::payments::PaymentsRequest, _>(
|
||||
merchant_account,
|
||||
business_profile,
|
||||
payment_data,
|
||||
None,
|
||||
customer,
|
||||
|
||||
Reference in New Issue
Block a user