diff --git a/crates/diesel_models/src/authorization.rs b/crates/diesel_models/src/authorization.rs index 8f9fc5721e..f8f95a046b 100644 --- a/crates/diesel_models/src/authorization.rs +++ b/crates/diesel_models/src/authorization.rs @@ -23,6 +23,7 @@ pub struct Authorization { pub error_message: Option, pub connector_authorization_id: Option, pub previously_authorized_amount: MinorUnit, + pub processor_merchant_id: Option, } #[derive(Clone, Debug, Insertable, router_derive::DebugAsDisplay, Serialize, Deserialize)] @@ -37,6 +38,7 @@ pub struct AuthorizationNew { pub error_message: Option, pub connector_authorization_id: Option, pub previously_authorized_amount: MinorUnit, + pub processor_merchant_id: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/crates/diesel_models/src/query/authorization.rs b/crates/diesel_models/src/query/authorization.rs index d0f75f523e..8423ed0f13 100644 --- a/crates/diesel_models/src/query/authorization.rs +++ b/crates/diesel_models/src/query/authorization.rs @@ -17,9 +17,9 @@ impl AuthorizationNew { } impl Authorization { - pub async fn update_by_merchant_id_authorization_id( + pub async fn update_by_processor_merchant_id_authorization_id( conn: &PgPooledConn, - merchant_id: common_utils::id_type::MerchantId, + processor_merchant_id: common_utils::id_type::MerchantId, authorization_id: String, authorization_update: AuthorizationUpdate, ) -> StorageResult { @@ -30,8 +30,8 @@ impl Authorization { _, >( conn, - dsl::merchant_id - .eq(merchant_id.to_owned()) + dsl::processor_merchant_id + .eq(processor_merchant_id.to_owned()) .and(dsl::authorization_id.eq(authorization_id.to_owned())), AuthorizationUpdateInternal::from(authorization_update), ) @@ -44,8 +44,8 @@ impl Authorization { errors::DatabaseError::NoFieldsToUpdate => { generics::generic_find_one::<::Table, _, _>( conn, - dsl::merchant_id - .eq(merchant_id.to_owned()) + dsl::processor_merchant_id + .eq(processor_merchant_id.to_owned()) .and(dsl::authorization_id.eq(authorization_id.to_owned())), ) .await @@ -56,15 +56,15 @@ impl Authorization { } } - pub async fn find_by_merchant_id_payment_id( + pub async fn find_by_processor_merchant_id_payment_id( conn: &PgPooledConn, - merchant_id: &common_utils::id_type::MerchantId, + processor_merchant_id: &common_utils::id_type::MerchantId, payment_id: &common_utils::id_type::PaymentId, ) -> StorageResult> { generics::generic_filter::<::Table, _, _, _>( conn, - dsl::merchant_id - .eq(merchant_id.to_owned()) + dsl::processor_merchant_id + .eq(processor_merchant_id.to_owned()) .and(dsl::payment_id.eq(payment_id.to_owned())), None, None, diff --git a/crates/diesel_models/src/schema.rs b/crates/diesel_models/src/schema.rs index 70f2fdf516..dc002d8736 100644 --- a/crates/diesel_models/src/schema.rs +++ b/crates/diesel_models/src/schema.rs @@ -760,6 +760,8 @@ diesel::table! { #[max_length = 64] connector_authorization_id -> Nullable, previously_authorized_amount -> Int8, + #[max_length = 64] + processor_merchant_id -> Nullable, } } diff --git a/crates/diesel_models/src/schema_v2.rs b/crates/diesel_models/src/schema_v2.rs index 9702c44637..4c27156a24 100644 --- a/crates/diesel_models/src/schema_v2.rs +++ b/crates/diesel_models/src/schema_v2.rs @@ -774,6 +774,8 @@ diesel::table! { #[max_length = 64] connector_authorization_id -> Nullable, previously_authorized_amount -> Int8, + #[max_length = 64] + processor_merchant_id -> Nullable, } } diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index 36b52046a2..69ef21dbce 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -561,7 +561,7 @@ pub async fn get_token_pm_type_mandate_details( verify_mandate_details_for_recurring_payments( &payment_method_info.merchant_id, - platform.get_processor().get_account().get_id(), + platform.get_provider().get_account().get_id(), &payment_method_info.customer_id, customer_id, )?; diff --git a/crates/router/src/core/payments/operations/payment_response.rs b/crates/router/src/core/payments/operations/payment_response.rs index 56ccf3ce99..b36cbb37dd 100644 --- a/crates/router/src/core/payments/operations/payment_response.rs +++ b/crates/router/src/core/payments/operations/payment_response.rs @@ -840,8 +840,8 @@ impl PostUpdateTracker, types::PaymentsIncrementalAu )?; state .store - .update_authorization_by_merchant_id_authorization_id( - router_data.merchant_id.clone(), + .update_authorization_by_processor_merchant_id_authorization_id( + payment_data.payment_intent.processor_merchant_id.clone(), authorization_id, authorization_update, ) @@ -851,8 +851,8 @@ impl PostUpdateTracker, types::PaymentsIncrementalAu //Fetch all the authorizations of the payment and send in incremental authorization response let authorizations = state .store - .find_all_authorizations_by_merchant_id_payment_id( - &router_data.merchant_id, + .find_all_authorizations_by_processor_merchant_id_payment_id( + &payment_data.payment_intent.processor_merchant_id, payment_data.payment_intent.get_id(), ) .await diff --git a/crates/router/src/core/payments/operations/payment_status.rs b/crates/router/src/core/payments/operations/payment_status.rs index d07beb66d7..5e18f1ad44 100644 --- a/crates/router/src/core/payments/operations/payment_status.rs +++ b/crates/router/src/core/payments/operations/payment_status.rs @@ -375,7 +375,7 @@ async fn get_tracker_for_sync< })?; let authorizations = db - .find_all_authorizations_by_merchant_id_payment_id( + .find_all_authorizations_by_processor_merchant_id_payment_id( platform.get_processor().get_account().get_id(), &payment_id, ) diff --git a/crates/router/src/core/payments/operations/payments_incremental_authorization.rs b/crates/router/src/core/payments/operations/payments_incremental_authorization.rs index 8b0bc88d89..4448053a1f 100644 --- a/crates/router/src/core/payments/operations/payments_incremental_authorization.rs +++ b/crates/router/src/core/payments/operations/payments_incremental_authorization.rs @@ -246,6 +246,7 @@ impl error_message: None, connector_authorization_id: None, previously_authorized_amount: payment_data.payment_attempt.get_total_amount(), + processor_merchant_id: Some(payment_data.payment_intent.processor_merchant_id.clone()), }; let authorization = state .store diff --git a/crates/router/src/db/authorization.rs b/crates/router/src/db/authorization.rs index 2440cbf83e..8465974afc 100644 --- a/crates/router/src/db/authorization.rs +++ b/crates/router/src/db/authorization.rs @@ -16,15 +16,15 @@ pub trait AuthorizationInterface { authorization: storage::AuthorizationNew, ) -> CustomResult; - async fn find_all_authorizations_by_merchant_id_payment_id( + async fn find_all_authorizations_by_processor_merchant_id_payment_id( &self, - merchant_id: &common_utils::id_type::MerchantId, + processor_merchant_id: &common_utils::id_type::MerchantId, payment_id: &common_utils::id_type::PaymentId, ) -> CustomResult, errors::StorageError>; - async fn update_authorization_by_merchant_id_authorization_id( + async fn update_authorization_by_processor_merchant_id_authorization_id( &self, - merchant_id: common_utils::id_type::MerchantId, + processor_merchant_id: common_utils::id_type::MerchantId, authorization_id: String, authorization: storage::AuthorizationUpdate, ) -> CustomResult; @@ -45,28 +45,32 @@ impl AuthorizationInterface for Store { } #[instrument(skip_all)] - async fn find_all_authorizations_by_merchant_id_payment_id( + async fn find_all_authorizations_by_processor_merchant_id_payment_id( &self, - merchant_id: &common_utils::id_type::MerchantId, + processor_merchant_id: &common_utils::id_type::MerchantId, payment_id: &common_utils::id_type::PaymentId, ) -> CustomResult, errors::StorageError> { let conn = connection::pg_connection_read(self).await?; - storage::Authorization::find_by_merchant_id_payment_id(&conn, merchant_id, payment_id) - .await - .map_err(|error| report!(errors::StorageError::from(error))) + storage::Authorization::find_by_processor_merchant_id_payment_id( + &conn, + processor_merchant_id, + payment_id, + ) + .await + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] - async fn update_authorization_by_merchant_id_authorization_id( + async fn update_authorization_by_processor_merchant_id_authorization_id( &self, - merchant_id: common_utils::id_type::MerchantId, + processor_merchant_id: common_utils::id_type::MerchantId, authorization_id: String, authorization: storage::AuthorizationUpdate, ) -> CustomResult { let conn = connection::pg_connection_write(self).await?; - storage::Authorization::update_by_merchant_id_authorization_id( + storage::Authorization::update_by_processor_merchant_id_authorization_id( &conn, - merchant_id, + processor_merchant_id, authorization_id, authorization, ) @@ -102,36 +106,40 @@ impl AuthorizationInterface for MockDb { error_message: authorization.error_message, connector_authorization_id: authorization.connector_authorization_id, previously_authorized_amount: authorization.previously_authorized_amount, + processor_merchant_id: authorization.processor_merchant_id, }; authorizations.push(authorization.clone()); Ok(authorization) } - async fn find_all_authorizations_by_merchant_id_payment_id( + async fn find_all_authorizations_by_processor_merchant_id_payment_id( &self, - merchant_id: &common_utils::id_type::MerchantId, + processor_merchant_id: &common_utils::id_type::MerchantId, payment_id: &common_utils::id_type::PaymentId, ) -> CustomResult, errors::StorageError> { let authorizations = self.authorizations.lock().await; let authorizations_found: Vec = authorizations .iter() - .filter(|a| a.merchant_id == *merchant_id && a.payment_id == *payment_id) + .filter(|a| { + a.processor_merchant_id.as_ref() == Some(processor_merchant_id) + && a.payment_id == *payment_id + }) .cloned() .collect(); Ok(authorizations_found) } - async fn update_authorization_by_merchant_id_authorization_id( + async fn update_authorization_by_processor_merchant_id_authorization_id( &self, - merchant_id: common_utils::id_type::MerchantId, + processor_merchant_id: common_utils::id_type::MerchantId, authorization_id: String, authorization_update: storage::AuthorizationUpdate, ) -> CustomResult { let mut authorizations = self.authorizations.lock().await; authorizations .iter_mut() - .find(|authorization| authorization.authorization_id == authorization_id && authorization.merchant_id == merchant_id) + .find(|authorization| authorization.authorization_id == authorization_id && authorization.processor_merchant_id.as_ref() == Some(&processor_merchant_id)) .map(|authorization| { let authorization_updated = AuthorizationUpdateInternal::from(authorization_update) @@ -141,7 +149,7 @@ impl AuthorizationInterface for MockDb { }) .ok_or( errors::StorageError::ValueNotFound(format!( - "cannot find authorization for authorization_id = {authorization_id} and merchant_id = {merchant_id:?}" + "cannot find authorization for authorization_id = {authorization_id} and processor_merchant_id = {processor_merchant_id:?}" )) .into(), ) diff --git a/crates/router/src/db/kafka_store.rs b/crates/router/src/db/kafka_store.rs index 55134a733a..d5400c4e42 100644 --- a/crates/router/src/db/kafka_store.rs +++ b/crates/router/src/db/kafka_store.rs @@ -3767,25 +3767,28 @@ impl AuthorizationInterface for KafkaStore { self.diesel_store.insert_authorization(authorization).await } - async fn find_all_authorizations_by_merchant_id_payment_id( + async fn find_all_authorizations_by_processor_merchant_id_payment_id( &self, - merchant_id: &id_type::MerchantId, + processor_merchant_id: &id_type::MerchantId, payment_id: &id_type::PaymentId, ) -> CustomResult, errors::StorageError> { self.diesel_store - .find_all_authorizations_by_merchant_id_payment_id(merchant_id, payment_id) + .find_all_authorizations_by_processor_merchant_id_payment_id( + processor_merchant_id, + payment_id, + ) .await } - async fn update_authorization_by_merchant_id_authorization_id( + async fn update_authorization_by_processor_merchant_id_authorization_id( &self, - merchant_id: id_type::MerchantId, + processor_merchant_id: id_type::MerchantId, authorization_id: String, authorization: storage::AuthorizationUpdate, ) -> CustomResult { self.diesel_store - .update_authorization_by_merchant_id_authorization_id( - merchant_id, + .update_authorization_by_processor_merchant_id_authorization_id( + processor_merchant_id, authorization_id, authorization, ) diff --git a/migrations/2026-02-03-102253_add_column_processor_merchant_id_in_incremetal_authorization/down.sql b/migrations/2026-02-03-102253_add_column_processor_merchant_id_in_incremetal_authorization/down.sql new file mode 100644 index 0000000000..2175901e44 --- /dev/null +++ b/migrations/2026-02-03-102253_add_column_processor_merchant_id_in_incremetal_authorization/down.sql @@ -0,0 +1,2 @@ +-- This file should undo anything in `up.sql` +ALTER TABLE incremental_authorization DROP COLUMN IF EXISTS processor_merchant_id; diff --git a/migrations/2026-02-03-102253_add_column_processor_merchant_id_in_incremetal_authorization/up.sql b/migrations/2026-02-03-102253_add_column_processor_merchant_id_in_incremetal_authorization/up.sql new file mode 100644 index 0000000000..cbd67c0626 --- /dev/null +++ b/migrations/2026-02-03-102253_add_column_processor_merchant_id_in_incremetal_authorization/up.sql @@ -0,0 +1,4 @@ +-- Your SQL goes here +ALTER TABLE incremental_authorization ADD COLUMN IF NOT EXISTS processor_merchant_id VARCHAR(64); +-- This backfill should be executed again after deployment +UPDATE incremental_authorization SET processor_merchant_id = merchant_id where processor_merchant_id IS NULL; \ No newline at end of file diff --git a/migrations/2026-02-03-113754_add_index_processor_merchant_id_authorization_id_for_incremental_authorization/down.sql b/migrations/2026-02-03-113754_add_index_processor_merchant_id_authorization_id_for_incremental_authorization/down.sql new file mode 100644 index 0000000000..b24c07aa42 --- /dev/null +++ b/migrations/2026-02-03-113754_add_index_processor_merchant_id_authorization_id_for_incremental_authorization/down.sql @@ -0,0 +1,2 @@ +-- This file should undo anything in `up.sql` +DROP INDEX CONCURRENTLY IF EXISTS incremental_authorization_processor_merchant_id_authorization_id_index; \ No newline at end of file diff --git a/migrations/2026-02-03-113754_add_index_processor_merchant_id_authorization_id_for_incremental_authorization/metadata.toml b/migrations/2026-02-03-113754_add_index_processor_merchant_id_authorization_id_for_incremental_authorization/metadata.toml new file mode 100644 index 0000000000..16153bc09f --- /dev/null +++ b/migrations/2026-02-03-113754_add_index_processor_merchant_id_authorization_id_for_incremental_authorization/metadata.toml @@ -0,0 +1 @@ +run_in_transaction = false \ No newline at end of file diff --git a/migrations/2026-02-03-113754_add_index_processor_merchant_id_authorization_id_for_incremental_authorization/up.sql b/migrations/2026-02-03-113754_add_index_processor_merchant_id_authorization_id_for_incremental_authorization/up.sql new file mode 100644 index 0000000000..cc59ddadf9 --- /dev/null +++ b/migrations/2026-02-03-113754_add_index_processor_merchant_id_authorization_id_for_incremental_authorization/up.sql @@ -0,0 +1,2 @@ +-- Your SQL goes here +CREATE INDEX CONCURRENTLY IF NOT EXISTS incremental_authorization_processor_merchant_id_authorization_id_index ON incremental_authorization (processor_merchant_id, authorization_id); \ No newline at end of file