Bug: [FEATURE] add profile acquirer module



### Feature Description

add profile acquirer create API, which allows us to create profile acquirer with the following fields
- profile_id
- acquirer_assigned_merchant_id
- merchant_name
- merchant_country_code
- network
- acquirer_bin
- acquirer_ica
- acquirer_fraud_rate

Acquirer details are stored in profile as a array of JSON object, and then to retrieve list of profile acquirers we can retrieve Business Profile

### Possible Implementation

add profile acquirer create api - POST `{{BASE_URL}}/profile_acquirer`, which accepts the acquirer details and stores it in profile table as JSONB (List of acquirers can be a added to a profile). retrieve business profile can be used to get the list of available profile acquirers. ProfileAcquirerId id_type can be used as unique identifier for each of the created record. 
diff --git a/crates/api_models/src/admin.rs b/crates/api_models/src/admin.rs
index 5ab7eae75f0..07f3e2431fa 100644
--- a/crates/api_models/src/admin.rs
+++ b/crates/api_models/src/admin.rs
@@ -2427,6 +2427,10 @@ pub struct ProfileResponse {
     #[schema(default = false, example = false)]
     pub is_pre_network_tokenization_enabled: bool,
 
+    /// Acquirer configs
+    #[schema(value_type = Option<AcquirerConfigMap>)]
+    pub acquirer_configs: Option<common_types::domain::AcquirerConfigMap>,
+
     /// Indicates if the redirection has to open in the iframe
     #[schema(example = false)]
     pub is_iframe_redirection_enabled: Option<bool>,
diff --git a/crates/api_models/src/lib.rs b/crates/api_models/src/lib.rs
index a2258e4bd5c..5fdb56e6966 100644
--- a/crates/api_models/src/lib.rs
+++ b/crates/api_models/src/lib.rs
@@ -32,6 +32,7 @@ pub mod payouts;
 pub mod pm_auth;
 pub mod poll;
 pub mod process_tracker;
+pub mod profile_acquirer;
 #[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
 pub mod proxy;
 #[cfg(feature = "recon")]
diff --git a/crates/api_models/src/profile_acquirer.rs b/crates/api_models/src/profile_acquirer.rs
new file mode 100644
index 00000000000..86f36db104a
--- /dev/null
+++ b/crates/api_models/src/profile_acquirer.rs
@@ -0,0 +1,66 @@
+use serde::{Deserialize, Serialize};
+use utoipa::ToSchema;
+
+use crate::enums;
+
+#[derive(Debug, Serialize, Deserialize, ToSchema)]
+pub struct ProfileAcquirerCreate {
+    /// The merchant id assigned by the acquirer
+    #[schema(value_type= String,example = "M123456789")]
+    pub acquirer_assigned_merchant_id: String,
+    /// merchant name
+    #[schema(value_type= String,example = "NewAge Retailer")]
+    pub merchant_name: String,
+    /// Merchant country code assigned by acquirer
+    #[schema(value_type= String,example = "US")]
+    pub merchant_country_code: enums::CountryAlpha2,
+    /// Network provider
+    #[schema(value_type= String,example = "VISA")]
+    pub network: common_enums::enums::CardNetwork,
+    /// Acquirer bin
+    #[schema(value_type= String,example = "456789")]
+    pub acquirer_bin: String,
+    /// Acquirer ica provided by acquirer
+    #[schema(value_type= Option<String>,example = "401288")]
+    pub acquirer_ica: Option<String>,
+    /// Fraud rate for the particular acquirer configuration
+    #[schema(value_type= f64,example = 0.01)]
+    pub acquirer_fraud_rate: f64,
+    /// Parent profile id to link the acquirer account with
+    #[schema(value_type= String,example = "pro_ky0yNyOXXlA5hF8JzE5q")]
+    pub profile_id: common_utils::id_type::ProfileId,
+}
+
+#[derive(Debug, Serialize, Deserialize, ToSchema)]
+pub struct ProfileAcquirerResponse {
+    /// The unique identifier of the profile acquirer
+    #[schema(value_type= String,example = "pro_acq_LCRdERuylQvNQ4qh3QE0")]
+    pub profile_acquirer_id: common_utils::id_type::ProfileAcquirerId,
+    /// The merchant id assigned by the acquirer
+    #[schema(value_type= String,example = "M123456789")]
+    pub acquirer_assigned_merchant_id: String,
+    /// Merchant name
+    #[schema(value_type= String,example = "NewAge Retailer")]
+    pub merchant_name: String,
+    /// Merchant country code assigned by acquirer
+    #[schema(value_type= String,example = "US")]
+    pub merchant_country_code: enums::CountryAlpha2,
+    /// Network provider
+    #[schema(value_type= String,example = "VISA")]
+    pub network: common_enums::enums::CardNetwork,
+    /// Acquirer bin
+    #[schema(value_type= String,example = "456789")]
+    pub acquirer_bin: String,
+    /// Acquirer ica provided by acquirer
+    #[schema(value_type= Option<String>,example = "401288")]
+    pub acquirer_ica: Option<String>,
+    /// Fraud rate for the particular acquirer configuration
+    #[schema(value_type= f64,example = 0.01)]
+    pub acquirer_fraud_rate: f64,
+    /// Parent profile id to link the acquirer account with
+    #[schema(value_type= String,example = "pro_ky0yNyOXXlA5hF8JzE5q")]
+    pub profile_id: common_utils::id_type::ProfileId,
+}
+
+impl common_utils::events::ApiEventMetric for ProfileAcquirerCreate {}
+impl common_utils::events::ApiEventMetric for ProfileAcquirerResponse {}
diff --git a/crates/common_types/src/domain.rs b/crates/common_types/src/domain.rs
index 0361f5b0e46..ca6a59abd6a 100644
--- a/crates/common_types/src/domain.rs
+++ b/crates/common_types/src/domain.rs
@@ -1,5 +1,7 @@
 //! Common types
 
+use std::collections::HashMap;
+
 use common_enums::enums;
 use common_utils::{impl_to_sql_from_sql_json, types::MinorUnit};
 use diesel::{sql_types::Jsonb, AsExpression, FromSqlRow};
@@ -53,3 +55,36 @@ pub struct XenditSplitSubMerchantData {
     pub for_user_id: String,
 }
 impl_to_sql_from_sql_json!(XenditSplitSubMerchantData);
+
+/// Acquirer configuration
+#[derive(Clone, Debug, Deserialize, ToSchema, Serialize, PartialEq)]
+pub struct AcquirerConfig {
+    /// The merchant id assigned by the acquirer
+    #[schema(value_type= String,example = "M123456789")]
+    pub acquirer_assigned_merchant_id: String,
+    /// merchant name
+    #[schema(value_type= String,example = "NewAge Retailer")]
+    pub merchant_name: String,
+    /// Merchant country code assigned by acquirer
+    #[schema(value_type= String,example = "US")]
+    pub merchant_country_code: common_enums::CountryAlpha2,
+    /// Network provider
+    #[schema(value_type= String,example = "VISA")]
+    pub network: common_enums::CardNetwork,
+    /// Acquirer bin
+    #[schema(value_type= String,example = "456789")]
+    pub acquirer_bin: String,
+    /// Acquirer ica provided by acquirer
+    #[schema(value_type= Option<String>,example = "401288")]
+    pub acquirer_ica: Option<String>,
+    /// Fraud rate for the particular acquirer configuration
+    #[schema(value_type= String,example = "0.01")]
+    pub acquirer_fraud_rate: f64,
+}
+
+#[derive(Serialize, Deserialize, Debug, Clone, FromSqlRow, AsExpression, ToSchema)]
+#[diesel(sql_type = Jsonb)]
+/// Acquirer configs
+pub struct AcquirerConfigMap(pub HashMap<common_utils::id_type::ProfileAcquirerId, AcquirerConfig>);
+
+impl_to_sql_from_sql_json!(AcquirerConfigMap);
diff --git a/crates/common_utils/src/events.rs b/crates/common_utils/src/events.rs
index 39a1694a7c1..b06fea4e1ea 100644
--- a/crates/common_utils/src/events.rs
+++ b/crates/common_utils/src/events.rs
@@ -126,6 +126,9 @@ pub enum ApiEventsType {
         token_id: Option<id_type::GlobalTokenId>,
     },
     ProcessTracker,
+    ProfileAcquirer {
+        profile_acquirer_id: id_type::ProfileAcquirerId,
+    },
     ThreeDsDecisionRule,
 }
 
diff --git a/crates/common_utils/src/id_type.rs b/crates/common_utils/src/id_type.rs
index 34a3844e76b..45b65c9a448 100644
--- a/crates/common_utils/src/id_type.rs
+++ b/crates/common_utils/src/id_type.rs
@@ -11,6 +11,7 @@ mod merchant_connector_account;
 mod organization;
 mod payment;
 mod profile;
+mod profile_acquirer;
 mod refunds;
 mod relay;
 mod routing;
@@ -46,6 +47,7 @@ pub use self::{
     organization::OrganizationId,
     payment::{PaymentId, PaymentReferenceId},
     profile::ProfileId,
+    profile_acquirer::ProfileAcquirerId,
     refunds::RefundReferenceId,
     relay::RelayId,
     routing::RoutingId,
diff --git a/crates/common_utils/src/id_type/profile_acquirer.rs b/crates/common_utils/src/id_type/profile_acquirer.rs
new file mode 100644
index 00000000000..ac5f09646bc
--- /dev/null
+++ b/crates/common_utils/src/id_type/profile_acquirer.rs
@@ -0,0 +1,41 @@
+use std::str::FromStr;
+
+crate::id_type!(
+    ProfileAcquirerId,
+    "A type for profile_acquirer_id that can be used for profile acquirer ids"
+);
+crate::impl_id_type_methods!(ProfileAcquirerId, "profile_acquirer_id");
+
+// This is to display the `ProfileAcquirerId` as ProfileAcquirerId(abcd)
+crate::impl_debug_id_type!(ProfileAcquirerId);
+crate::impl_try_from_cow_str_id_type!(ProfileAcquirerId, "profile_acquirer_id");
+
+crate::impl_generate_id_id_type!(ProfileAcquirerId, "pro_acq");
+crate::impl_serializable_secret_id_type!(ProfileAcquirerId);
+crate::impl_queryable_id_type!(ProfileAcquirerId);
+crate::impl_to_sql_from_sql_id_type!(ProfileAcquirerId);
+
+impl crate::events::ApiEventMetric for ProfileAcquirerId {
+    fn get_api_event_type(&self) -> Option<crate::events::ApiEventsType> {
+        Some(crate::events::ApiEventsType::ProfileAcquirer {
+            profile_acquirer_id: self.clone(),
+        })
+    }
+}
+
+impl FromStr for ProfileAcquirerId {
+    type Err = error_stack::Report<crate::errors::ValidationError>;
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        let cow_string = std::borrow::Cow::Owned(s.to_string());
+        Self::try_from(cow_string)
+    }
+}
+
+// This is implemented so that we can use profile acquirer id directly as attribute in metrics
+#[cfg(feature = "metrics")]
+impl From<ProfileAcquirerId> for router_env::opentelemetry::Value {
+    fn from(val: ProfileAcquirerId) -> Self {
+        Self::from(val.0 .0 .0)
+    }
+}
diff --git a/crates/common_utils/src/lib.rs b/crates/common_utils/src/lib.rs
index 759329ba327..3f491d3e9a6 100644
--- a/crates/common_utils/src/lib.rs
+++ b/crates/common_utils/src/lib.rs
@@ -253,6 +253,13 @@ pub fn generate_merchant_connector_account_id_of_default_length(
     id_type::MerchantConnectorAccountId::generate()
 }
 
+/// Generate a profile_acquirer id with default length, with prefix as `mer_acq`
+pub fn generate_profile_acquirer_id_of_default_length() -> id_type::ProfileAcquirerId {
+    use id_type::GenerateId;
+
+    id_type::ProfileAcquirerId::generate()
+}
+
 /// Generate a nanoid with the given prefix and a default length
 #[inline]
 pub fn generate_id_with_default_len(prefix: &str) -> String {
diff --git a/crates/diesel_models/src/business_profile.rs b/crates/diesel_models/src/business_profile.rs
index 848f673f502..a93bab30a49 100644
--- a/crates/diesel_models/src/business_profile.rs
+++ b/crates/diesel_models/src/business_profile.rs
@@ -74,6 +74,7 @@ pub struct Profile {
     pub is_iframe_redirection_enabled: Option<bool>,
     pub is_pre_network_tokenization_enabled: Option<bool>,
     pub three_ds_decision_rule_algorithm: Option<serde_json::Value>,
+    pub acquirer_config_map: Option<common_types::domain::AcquirerConfigMap>,
 }
 
 #[cfg(feature = "v1")]
@@ -183,6 +184,7 @@ pub struct ProfileUpdateInternal {
     pub is_iframe_redirection_enabled: Option<bool>,
     pub is_pre_network_tokenization_enabled: Option<bool>,
     pub three_ds_decision_rule_algorithm: Option<serde_json::Value>,
+    pub acquirer_config_map: Option<common_types::domain::AcquirerConfigMap>,
 }
 
 #[cfg(feature = "v1")]
@@ -234,6 +236,7 @@ impl ProfileUpdateInternal {
             is_iframe_redirection_enabled,
             is_pre_network_tokenization_enabled,
             three_ds_decision_rule_algorithm,
+            acquirer_config_map,
         } = self;
         Profile {
             profile_id: source.profile_id,
@@ -316,6 +319,7 @@ impl ProfileUpdateInternal {
                 .or(source.is_pre_network_tokenization_enabled),
             three_ds_decision_rule_algorithm: three_ds_decision_rule_algorithm
                 .or(source.three_ds_decision_rule_algorithm),
+            acquirer_config_map: acquirer_config_map.or(source.acquirer_config_map),
         }
     }
 }
@@ -376,6 +380,7 @@ pub struct Profile {
     pub id: common_utils::id_type::ProfileId,
     pub is_iframe_redirection_enabled: Option<bool>,
     pub three_ds_decision_rule_algorithm: Option<serde_json::Value>,
+    pub acquirer_config_map: Option<common_types::domain::AcquirerConfigMap>,
     pub routing_algorithm_id: Option<common_utils::id_type::RoutingId>,
     pub order_fulfillment_time: Option<i64>,
     pub order_fulfillment_time_origin: Option<common_enums::OrderFulfillmentTimeOrigin>,
@@ -665,6 +670,7 @@ impl ProfileUpdateInternal {
             external_vault_connector_details: external_vault_connector_details
                 .or(source.external_vault_connector_details),
             three_ds_decision_rule_algorithm: None,
+            acquirer_config_map: None,
         }
     }
 }
diff --git a/crates/diesel_models/src/schema.rs b/crates/diesel_models/src/schema.rs
index 388fcc23759..4e93ecab944 100644
--- a/crates/diesel_models/src/schema.rs
+++ b/crates/diesel_models/src/schema.rs
@@ -228,6 +228,7 @@ diesel::table! {
         is_iframe_redirection_enabled -> Nullable<Bool>,
         is_pre_network_tokenization_enabled -> Nullable<Bool>,
         three_ds_decision_rule_algorithm -> Nullable<Jsonb>,
+        acquirer_config_map -> Nullable<Jsonb>,
     }
 }
 
diff --git a/crates/diesel_models/src/schema_v2.rs b/crates/diesel_models/src/schema_v2.rs
index 5b1201027b7..0c6bdadac84 100644
--- a/crates/diesel_models/src/schema_v2.rs
+++ b/crates/diesel_models/src/schema_v2.rs
@@ -223,6 +223,7 @@ diesel::table! {
         id -> Varchar,
         is_iframe_redirection_enabled -> Nullable<Bool>,
         three_ds_decision_rule_algorithm -> Nullable<Jsonb>,
+        acquirer_config_map -> Nullable<Jsonb>,
         #[max_length = 64]
         routing_algorithm_id -> Nullable<Varchar>,
         order_fulfillment_time -> Nullable<Int8>,
diff --git a/crates/hyperswitch_domain_models/src/business_profile.rs b/crates/hyperswitch_domain_models/src/business_profile.rs
index 80070aa9e50..6c95af4f149 100644
--- a/crates/hyperswitch_domain_models/src/business_profile.rs
+++ b/crates/hyperswitch_domain_models/src/business_profile.rs
@@ -76,6 +76,7 @@ pub struct Profile {
     pub is_iframe_redirection_enabled: Option<bool>,
     pub is_pre_network_tokenization_enabled: bool,
     pub three_ds_decision_rule_algorithm: Option<serde_json::Value>,
+    pub acquirer_config_map: Option<common_types::domain::AcquirerConfigMap>,
 }
 
 #[cfg(feature = "v1")]
@@ -188,6 +189,7 @@ impl From<ProfileSetter> for Profile {
             is_iframe_redirection_enabled: value.is_iframe_redirection_enabled,
             is_pre_network_tokenization_enabled: value.is_pre_network_tokenization_enabled,
             three_ds_decision_rule_algorithm: None, // three_ds_decision_rule_algorithm is not yet created during profile creation
+            acquirer_config_map: None,
         }
     }
 }
@@ -274,6 +276,9 @@ pub enum ProfileUpdate {
     CardTestingSecretKeyUpdate {
         card_testing_secret_key: OptionalEncryptableName,
     },
+    AcquirerConfigMapUpdate {
+        acquirer_config_map: Option<common_types::domain::AcquirerConfigMap>,
+    },
 }
 
 #[cfg(feature = "v1")]
@@ -373,6 +378,7 @@ impl From<ProfileUpdate> for ProfileUpdateInternal {
                     is_iframe_redirection_enabled,
                     is_pre_network_tokenization_enabled,
                     three_ds_decision_rule_algorithm: None,
+                    acquirer_config_map: None,
                 }
             }
             ProfileUpdate::RoutingAlgorithmUpdate {
@@ -425,6 +431,7 @@ impl From<ProfileUpdate> for ProfileUpdateInternal {
                 is_iframe_redirection_enabled: None,
                 is_pre_network_tokenization_enabled: None,
                 three_ds_decision_rule_algorithm,
+                acquirer_config_map: None,
             },
             ProfileUpdate::DynamicRoutingAlgorithmUpdate {
                 dynamic_routing_algorithm,
@@ -474,6 +481,7 @@ impl From<ProfileUpdate> for ProfileUpdateInternal {
                 is_iframe_redirection_enabled: None,
                 is_pre_network_tokenization_enabled: None,
                 three_ds_decision_rule_algorithm: None,
+                acquirer_config_map: None,
             },
             ProfileUpdate::ExtendedCardInfoUpdate {
                 is_extended_card_info_enabled,
@@ -523,6 +531,7 @@ impl From<ProfileUpdate> for ProfileUpdateInternal {
                 is_iframe_redirection_enabled: None,
                 is_pre_network_tokenization_enabled: None,
                 three_ds_decision_rule_algorithm: None,
+                acquirer_config_map: None,
             },
             ProfileUpdate::ConnectorAgnosticMitUpdate {
                 is_connector_agnostic_mit_enabled,
@@ -572,6 +581,7 @@ impl From<ProfileUpdate> for ProfileUpdateInternal {
                 is_iframe_redirection_enabled: None,
                 is_pre_network_tokenization_enabled: None,
                 three_ds_decision_rule_algorithm: None,
+                acquirer_config_map: None,
             },
             ProfileUpdate::NetworkTokenizationUpdate {
                 is_network_tokenization_enabled,
@@ -621,6 +631,7 @@ impl From<ProfileUpdate> for ProfileUpdateInternal {
                 is_iframe_redirection_enabled: None,
                 is_pre_network_tokenization_enabled: None,
                 three_ds_decision_rule_algorithm: None,
+                acquirer_config_map: None,
             },
             ProfileUpdate::CardTestingSecretKeyUpdate {
                 card_testing_secret_key,
@@ -670,6 +681,57 @@ impl From<ProfileUpdate> for ProfileUpdateInternal {
                 is_iframe_redirection_enabled: None,
                 is_pre_network_tokenization_enabled: None,
                 three_ds_decision_rule_algorithm: None,
+                acquirer_config_map: None,
+            },
+            ProfileUpdate::AcquirerConfigMapUpdate {
+                acquirer_config_map,
+            } => Self {
+                profile_name: None,
+                modified_at: now,
+                return_url: None,
+                enable_payment_response_hash: None,
+                payment_response_hash_key: None,
+                redirect_to_merchant_with_http_post: None,
+                webhook_details: None,
+                metadata: None,
+                routing_algorithm: None,
+                intent_fulfillment_time: None,
+                frm_routing_algorithm: None,
+                payout_routing_algorithm: None,
+                is_recon_enabled: None,
+                applepay_verified_domains: None,
+                payment_link_config: None,
+                session_expiry: None,
+                authentication_connector_details: None,
+                payout_link_config: None,
+                is_extended_card_info_enabled: None,
+                extended_card_info_config: None,
+                is_connector_agnostic_mit_enabled: None,
+                use_billing_as_payment_method_billing: None,
+                collect_shipping_details_from_wallet_connector: None,
+                collect_billing_details_from_wallet_connector: None,
+                outgoing_webhook_custom_http_headers: None,
+                always_collect_billing_details_from_wallet_connector: None,
+                always_collect_shipping_details_from_wallet_connector: None,
+                tax_connector_id: None,
+                is_tax_connector_enabled: None,
+                dynamic_routing_algorithm: None,
+                is_network_tokenization_enabled: None,
+                is_auto_retries_enabled: None,
+                max_auto_retries_enabled: None,
+                always_request_extended_authorization: None,
+                is_click_to_pay_enabled: None,
+                authentication_product_ids: None,
+                card_testing_guard_config: None,
+                card_testing_secret_key: None,
+                is_clear_pan_retries_enabled: None,
+                force_3ds_challenge: None,
+                is_debit_routing_enabled: None,
+                merchant_business_country: None,
+                is_iframe_redirection_enabled: None,
+                is_pre_network_tokenization_enabled: None,
+                three_ds_decision_rule_algorithm: None,
+                acquirer_config_map,
             },
         }
     }
@@ -739,6 +801,7 @@ impl super::behaviour::Conversion for Profile {
             is_iframe_redirection_enabled: self.is_iframe_redirection_enabled,
             is_pre_network_tokenization_enabled: Some(self.is_pre_network_tokenization_enabled),
             three_ds_decision_rule_algorithm: self.three_ds_decision_rule_algorithm,
+            acquirer_config_map: self.acquirer_config_map,
         })
     }
 
@@ -834,6 +897,7 @@ impl super::behaviour::Conversion for Profile {
                     .is_pre_network_tokenization_enabled
                     .unwrap_or(false),
                 three_ds_decision_rule_algorithm: item.three_ds_decision_rule_algorithm,
+                acquirer_config_map: item.acquirer_config_map,
             })
         }
         .await
@@ -1825,6 +1889,7 @@ impl super::behaviour::Conversion for Profile {
             is_external_vault_enabled: self.is_external_vault_enabled,
             external_vault_connector_details: self.external_vault_connector_details,
             three_ds_decision_rule_algorithm: None,
+            acquirer_config_map: None,
         })
     }
 
diff --git a/crates/openapi/src/openapi.rs b/crates/openapi/src/openapi.rs
index d0585fd98cc..4f8b96d5fbe 100644
--- a/crates/openapi/src/openapi.rs
+++ b/crates/openapi/src/openapi.rs
@@ -203,6 +203,9 @@ Never share your secret api keys. Keep them guarded and secure.
         // Routes for poll apis
         routes::poll::retrieve_poll_status,
 
+        // Routes for profile acquirer account
+        routes::profile_acquirer::profile_acquirer_create,
+
         // Routes for 3DS Decision Rule
         routes::three_ds_decision_rule::three_ds_decision_rule_execute,
     ),
@@ -274,6 +277,8 @@ Never share your secret api keys. Keep them guarded and secure.
         api_models::payment_methods::PaymentMethodResponse,
         api_models::payment_methods::CustomerPaymentMethod,
         common_types::three_ds_decision_rule_engine::ThreeDSDecisionRule,
+        common_types::domain::AcquirerConfigMap,
+        common_types::domain::AcquirerConfig,
         api_models::payment_methods::PaymentMethodListResponse,
         api_models::payment_methods::ResponsePaymentMethodsEnabled,
         api_models::payment_methods::ResponsePaymentMethodTypes,
@@ -773,6 +778,8 @@ Never share your secret api keys. Keep them guarded and secure.
         api_models::open_router::DecisionEngineGatewayWiseExtraScore,
         api_models::open_router::DecisionEngineSRSubLevelInputConfig,
         api_models::open_router::DecisionEngineEliminationData,
+        api_models::profile_acquirer::ProfileAcquirerCreate,
+        api_models::profile_acquirer::ProfileAcquirerResponse,
         euclid::frontend::dir::enums::CustomerDevicePlatform,
         euclid::frontend::dir::enums::CustomerDeviceType,
         euclid::frontend::dir::enums::CustomerDeviceDisplaySize,
diff --git a/crates/openapi/src/routes.rs b/crates/openapi/src/routes.rs
index 23d9a79a4de..c91dd74f0fe 100644
--- a/crates/openapi/src/routes.rs
+++ b/crates/openapi/src/routes.rs
@@ -15,6 +15,7 @@ pub mod payments;
 pub mod payouts;
 pub mod poll;
 pub mod profile;
+pub mod profile_acquirer;
 pub mod proxy;
 pub mod refunds;
 pub mod relay;
diff --git a/crates/openapi/src/routes/profile_acquirer.rs b/crates/openapi/src/routes/profile_acquirer.rs
new file mode 100644
index 00000000000..2c3467aeb63
--- /dev/null
+++ b/crates/openapi/src/routes/profile_acquirer.rs
@@ -0,0 +1,18 @@
+#[cfg(feature = "v1")]
+/// Profile Acquirer - Create
+///
+/// Create a new Profile Acquirer for accessing our APIs from your servers.
+#[utoipa::path(
+    post,
+    path = "/profile_acquirers",
+    request_body = ProfileAcquirerCreate,
+    responses(
+        (status = 200, description = "Profile Acquirer created", body = ProfileAcquirerResponse),
+        (status = 400, description = "Invalid data")
+    ),
+    tag = "Profile Acquirer",
+    operation_id = "Create a Profile Acquirer",
+    security(("api_key" = []))
+)]
+pub async fn profile_acquirer_create() { /* … */
+}
diff --git a/crates/router/src/core.rs b/crates/router/src/core.rs
index e5e97b5dc0b..a46f9742798 100644
--- a/crates/router/src/core.rs
+++ b/crates/router/src/core.rs
@@ -61,6 +61,7 @@ pub mod verification;
 pub mod verify_connector;
 pub mod webhooks;
 
+pub mod profile_acquirer;
 pub mod unified_authentication_service;
 
 #[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
diff --git a/crates/router/src/core/payouts.rs b/crates/router/src/core/payouts.rs
index ebc462d286d..04b3e05d1e9 100644
--- a/crates/router/src/core/payouts.rs
+++ b/crates/router/src/core/payouts.rs
@@ -372,13 +372,13 @@ pub async fn payouts_confirm_core(
     merchant_context: domain::MerchantContext,
     req: payouts::PayoutCreateRequest,
 ) -> RouterResponse<payouts::PayoutCreateResponse> {
-    let mut payout_data = make_payout_data(
+    let mut payout_data = Box::pin(make_payout_data(
         &state,
         &merchant_context,
         None,
         &payouts::PayoutRequest::PayoutCreateRequest(Box::new(req.to_owned())),
         &state.locale,
-    )
+    ))
     .await?;
     let payout_attempt = payout_data.payout_attempt.to_owned();
     let status = payout_attempt.status;
@@ -435,13 +435,13 @@ pub async fn payouts_update_core(
     req: payouts::PayoutCreateRequest,
 ) -> RouterResponse<payouts::PayoutCreateResponse> {
     let payout_id = req.payout_id.clone().get_required_value("payout_id")?;
-    let mut payout_data = make_payout_data(
+    let mut payout_data = Box::pin(make_payout_data(
         &state,
         &merchant_context,
         None,
         &payouts::PayoutRequest::PayoutCreateRequest(Box::new(req.to_owned())),
         &state.locale,
-    )
+    ))
     .await?;
 
     let payout_attempt = payout_data.payout_attempt.to_owned();
@@ -509,13 +509,13 @@ pub async fn payouts_retrieve_core(
     profile_id: Option<common_utils::id_type::ProfileId>,
     req: payouts::PayoutRetrieveRequest,
 ) -> RouterResponse<payouts::PayoutCreateResponse> {
-    let mut payout_data = make_payout_data(
+    let mut payout_data = Box::pin(make_payout_data(
         &state,
         &merchant_context,
         profile_id,
         &payouts::PayoutRequest::PayoutRetrieveRequest(req.to_owned()),
         &state.locale,
-    )
+    ))
     .await?;
     let payout_attempt = payout_data.payout_attempt.to_owned();
     let status = payout_attempt.status;
@@ -550,13 +550,13 @@ pub async fn payouts_cancel_core(
     merchant_context: domain::MerchantContext,
     req: payouts::PayoutActionRequest,
 ) -> RouterResponse<payouts::PayoutCreateResponse> {
-    let mut payout_data = make_payout_data(
+    let mut payout_data = Box::pin(make_payout_data(
         &state,
         &merchant_context,
         None,
         &payouts::PayoutRequest::PayoutActionRequest(req.to_owned()),
         &state.locale,
-    )
+    ))
     .await?;
 
     let payout_attempt = payout_data.payout_attempt.to_owned();
@@ -641,13 +641,13 @@ pub async fn payouts_fulfill_core(
     merchant_context: domain::MerchantContext,
     req: payouts::PayoutActionRequest,
 ) -> RouterResponse<payouts::PayoutCreateResponse> {
-    let mut payout_data = make_payout_data(
+    let mut payout_data = Box::pin(make_payout_data(
         &state,
         &merchant_context,
         None,
         &payouts::PayoutRequest::PayoutActionRequest(req.to_owned()),
         &state.locale,
-    )
+    ))
     .await?;
 
     let payout_attempt = payout_data.payout_attempt.to_owned();
diff --git a/crates/router/src/core/profile_acquirer.rs b/crates/router/src/core/profile_acquirer.rs
new file mode 100644
index 00000000000..747059e540e
--- /dev/null
+++ b/crates/router/src/core/profile_acquirer.rs
@@ -0,0 +1,114 @@
+use api_models::profile_acquirer;
+use common_utils::types::keymanager::KeyManagerState;
+use error_stack::ResultExt;
+
+use crate::{
+    core::errors::{self, utils::StorageErrorExt, RouterResponse},
+    services::api,
+    types::domain,
+    SessionState,
+};
+
+#[cfg(all(feature = "olap", feature = "v1"))]
+pub async fn create_profile_acquirer(
+    state: SessionState,
+    request: profile_acquirer::ProfileAcquirerCreate,
+    merchant_context: domain::MerchantContext,
+) -> RouterResponse<profile_acquirer::ProfileAcquirerResponse> {
+    let db = state.store.as_ref();
+    let profile_acquirer_id = common_utils::generate_profile_acquirer_id_of_default_length();
+    let key_manager_state: KeyManagerState = (&state).into();
+    let merchant_key_store = merchant_context.get_merchant_key_store();
+
+    let mut business_profile = db
+        .find_business_profile_by_profile_id(
+            &key_manager_state,
+            merchant_key_store,
+            &request.profile_id,
+        )
+        .await
+        .to_not_found_response(errors::ApiErrorResponse::ProfileNotFound {
+            id: request.profile_id.get_string_repr().to_owned(),
+        })?;
+
+    let incoming_acquirer_config = common_types::domain::AcquirerConfig {
+        acquirer_assigned_merchant_id: request.acquirer_assigned_merchant_id.clone(),
+        merchant_name: request.merchant_name.clone(),
+        merchant_country_code: request.merchant_country_code,
+        network: request.network.clone(),
+        acquirer_bin: request.acquirer_bin.clone(),
+        acquirer_ica: request.acquirer_ica.clone(),
+        acquirer_fraud_rate: request.acquirer_fraud_rate,
+    };
+
+    // Check for duplicates before proceeding
+
+    business_profile
+        .acquirer_config_map
+        .as_ref()
+        .map_or(Ok(()), |configs_wrapper| {
+            match configs_wrapper.0.values().any(|existing_config| existing_config == &incoming_acquirer_config) {
+                true => Err(error_stack::report!(
+                    errors::ApiErrorResponse::GenericDuplicateError {
+                        message: format!(
+                            "Duplicate acquirer configuration found for profile_id: {}. Conflicting configuration: {:?}",
+                            request.profile_id.get_string_repr(),
+                            incoming_acquirer_config
+                        ),
+                    }
+                )),
+                false => Ok(()),
+            }
+        })?;
+
+    // Get a mutable reference to the HashMap inside AcquirerConfigMap,
+    // initializing if it's None or the inner HashMap is not present.
+    let configs_map = &mut business_profile
+        .acquirer_config_map
+        .get_or_insert_with(|| {
+            common_types::domain::AcquirerConfigMap(std::collections::HashMap::new())
+        })
+        .0;
+
+    configs_map.insert(
+        profile_acquirer_id.clone(),
+        incoming_acquirer_config.clone(),
+    );
+
+    let profile_update = domain::ProfileUpdate::AcquirerConfigMapUpdate {
+        acquirer_config_map: business_profile.acquirer_config_map.clone(),
+    };
+    let updated_business_profile = db
+        .update_profile_by_profile_id(
+            &key_manager_state,
+            merchant_key_store,
+            business_profile,
+            profile_update,
+        )
+        .await
+        .change_context(errors::ApiErrorResponse::InternalServerError)
+        .attach_printable("Failed to update business profile with new acquirer config")?;
+
+    let updated_acquire_details = updated_business_profile
+        .acquirer_config_map
+        .as_ref()
+        .and_then(|acquirer_configs_wrapper| acquirer_configs_wrapper.0.get(&profile_acquirer_id))
+        .ok_or(errors::ApiErrorResponse::InternalServerError)
+        .attach_printable("Failed to get updated acquirer config")?;
+
+    let response = profile_acquirer::ProfileAcquirerResponse {
+        profile_acquirer_id,
+        profile_id: request.profile_id.clone(),
+        acquirer_assigned_merchant_id: updated_acquire_details
+            .acquirer_assigned_merchant_id
+            .clone(),
+        merchant_name: updated_acquire_details.merchant_name.clone(),
+        merchant_country_code: updated_acquire_details.merchant_country_code,
+        network: updated_acquire_details.network.clone(),
+        acquirer_bin: updated_acquire_details.acquirer_bin.clone(),
+        acquirer_ica: updated_acquire_details.acquirer_ica.clone(),
+        acquirer_fraud_rate: updated_acquire_details.acquirer_fraud_rate,
+    };
+
+    Ok(api::ApplicationResponse::Json(response))
+}
diff --git a/crates/router/src/core/webhooks/incoming.rs b/crates/router/src/core/webhooks/incoming.rs
index a7a0c76e2f0..3f95d61bfb7 100644
--- a/crates/router/src/core/webhooks/incoming.rs
+++ b/crates/router/src/core/webhooks/incoming.rs
@@ -822,13 +822,13 @@ async fn payouts_incoming_webhook_flow(
                 payout_id: payouts.payout_id.clone(),
             });
 
-        let payout_data = payouts::make_payout_data(
+        let payout_data = Box::pin(payouts::make_payout_data(
             &state,
             &merchant_context,
             None,
             &action_req,
             common_utils::consts::DEFAULT_LOCALE,
-        )
+        ))
         .await?;
 
         let updated_payout_attempt = db
diff --git a/crates/router/src/db/kafka_store.rs b/crates/router/src/db/kafka_store.rs
index e34fad3a2b1..e7136919cee 100644
--- a/crates/router/src/db/kafka_store.rs
+++ b/crates/router/src/db/kafka_store.rs
@@ -10,8 +10,7 @@ use common_utils::{
 #[cfg(feature = "v2")]
 use diesel_models::ephemeral_key::{ClientSecretType, ClientSecretTypeNew};
 use diesel_models::{
-    enums,
-    enums::ProcessTrackerStatus,
+    enums::{self, ProcessTrackerStatus},
     ephemeral_key::{EphemeralKey, EphemeralKeyNew},
     reverse_lookup::{ReverseLookup, ReverseLookupNew},
     user_role as user_storage,
diff --git a/crates/router/src/lib.rs b/crates/router/src/lib.rs
index f37b404de41..6a048c59b00 100644
--- a/crates/router/src/lib.rs
+++ b/crates/router/src/lib.rs
@@ -132,7 +132,8 @@ pub fn mk_app(
             {
                 server_app = server_app
                     .service(routes::ProfileNew::server(state.clone()))
-                    .service(routes::Forex::server(state.clone()));
+                    .service(routes::Forex::server(state.clone()))
+                    .service(routes::ProfileAcquirer::server(state.clone()));
             }
 
             server_app = server_app.service(routes::Profile::server(state.clone()));
diff --git a/crates/router/src/routes.rs b/crates/router/src/routes.rs
index 7002a725b79..35221104ae3 100644
--- a/crates/router/src/routes.rs
+++ b/crates/router/src/routes.rs
@@ -41,6 +41,8 @@ pub mod payouts;
 pub mod pm_auth;
 pub mod poll;
 #[cfg(feature = "olap")]
+pub mod profile_acquirer;
+#[cfg(feature = "olap")]
 pub mod profiles;
 #[cfg(feature = "recon")]
 pub mod recon;
@@ -86,8 +88,8 @@ pub use self::app::{
     ApiKeys, AppState, ApplePayCertificatesMigration, Cache, Cards, Configs, ConnectorOnboarding,
     Customers, Disputes, EphemeralKey, FeatureMatrix, Files, Forex, Gsm, Health, Hypersense,
     Mandates, MerchantAccount, MerchantConnectorAccount, PaymentLink, PaymentMethods, Payments,
-    Poll, ProcessTracker, Profile, ProfileNew, Refunds, Relay, RelayWebhooks, SessionState,
-    ThreeDsDecisionRule, User, Webhooks,
+    Poll, ProcessTracker, Profile, ProfileAcquirer, ProfileNew, Refunds, Relay, RelayWebhooks,
+    SessionState, ThreeDsDecisionRule, User, Webhooks,
 };
 #[cfg(feature = "olap")]
 pub use self::app::{Blocklist, Organization, Routing, Verify, WebhookEvents};
diff --git a/crates/router/src/routes/app.rs b/crates/router/src/routes/app.rs
index 82c3e10105e..3d2a6e91700 100644
--- a/crates/router/src/routes/app.rs
+++ b/crates/router/src/routes/app.rs
@@ -85,6 +85,8 @@ use crate::routes::cards_info::{
 use crate::routes::feature_matrix;
 #[cfg(all(feature = "frm", feature = "oltp"))]
 use crate::routes::fraud_check as frm_routes;
+#[cfg(all(feature = "olap", feature = "v1"))]
+use crate::routes::profile_acquirer;
 #[cfg(all(feature = "recon", feature = "olap"))]
 use crate::routes::recon as recon_routes;
 pub use crate::{
@@ -2645,3 +2647,17 @@ impl ProcessTracker {
             )
     }
 }
+
+#[cfg(feature = "olap")]
+pub struct ProfileAcquirer;
+
+#[cfg(all(feature = "olap", feature = "v1"))]
+impl ProfileAcquirer {
+    pub fn server(state: AppState) -> Scope {
+        web::scope("/profile_acquirer")
+            .app_data(web::Data::new(state))
+            .service(
+                web::resource("").route(web::post().to(profile_acquirer::create_profile_acquirer)),
+            )
+    }
+}
diff --git a/crates/router/src/routes/lock_utils.rs b/crates/router/src/routes/lock_utils.rs
index 91225fa39ab..9f64e31dcff 100644
--- a/crates/router/src/routes/lock_utils.rs
+++ b/crates/router/src/routes/lock_utils.rs
@@ -44,6 +44,7 @@ pub enum ApiIdentifier {
     PaymentMethodSession,
     ProcessTracker,
     Proxy,
+    ProfileAcquirer,
     ThreeDsDecisionRule,
     GenericTokenization,
 }
@@ -345,6 +346,7 @@ impl From<Flow> for ApiIdentifier {
             Flow::RevenueRecoveryRetrieve => Self::ProcessTracker,
             Flow::Proxy => Self::Proxy,
 
+            Flow::ProfileAcquirerCreate => Self::ProfileAcquirer,
             Flow::ThreeDsDecisionRuleExecute => Self::ThreeDsDecisionRule,
             Flow::TokenizationCreate | Flow::TokenizationRetrieve => Self::GenericTokenization,
         }
diff --git a/crates/router/src/routes/profile_acquirer.rs b/crates/router/src/routes/profile_acquirer.rs
new file mode 100644
index 00000000000..4e8a5eeffaf
--- /dev/null
+++ b/crates/router/src/routes/profile_acquirer.rs
@@ -0,0 +1,50 @@
+use actix_web::{web, HttpRequest, HttpResponse};
+use api_models::profile_acquirer::ProfileAcquirerCreate;
+use router_env::{instrument, tracing, Flow};
+
+use super::app::AppState;
+use crate::{
+    core::api_locking,
+    services::{api, authentication as auth, authorization::permissions::Permission},
+    types::domain,
+};
+
+#[cfg(all(feature = "olap", feature = "v1"))]
+#[instrument(skip_all, fields(flow = ?Flow::ProfileAcquirerCreate))]
+pub async fn create_profile_acquirer(
+    state: web::Data<AppState>,
+    req: HttpRequest,
+    json_payload: web::Json<ProfileAcquirerCreate>,
+) -> HttpResponse {
+    let flow = Flow::ProfileAcquirerCreate;
+    let payload = json_payload.into_inner();
+
+    Box::pin(api::server_wrap(
+        flow,
+        state,
+        &req,
+        payload,
+        |state: super::SessionState, auth_data, req, _| {
+            let merchant_context = domain::MerchantContext::NormalMerchant(Box::new(
+                domain::Context(auth_data.merchant_account, auth_data.key_store),
+            ));
+            crate::core::profile_acquirer::create_profile_acquirer(
+                state,
+                req,
+                merchant_context.clone(),
+            )
+        },
+        auth::auth_type(
+            &auth::HeaderAuth(auth::ApiKeyAuth {
+                is_connected_allowed: false,
+                is_platform_allowed: true,
+            }),
+            &auth::JWTAuth {
+                permission: Permission::ProfileAccountWrite,
+            },
+            req.headers(),
+        ),
+        api_locking::LockAction::NotApplicable,
+    ))
+    .await
+}
diff --git a/crates/router/src/types/api/admin.rs b/crates/router/src/types/api/admin.rs
index cbca021f1c9..41069a784b8 100644
--- a/crates/router/src/types/api/admin.rs
+++ b/crates/router/src/types/api/admin.rs
@@ -197,6 +197,7 @@ impl ForeignTryFrom<domain::Profile> for ProfileResponse {
             is_debit_routing_enabled: Some(item.is_debit_routing_enabled),
             merchant_business_country: item.merchant_business_country,
             is_pre_network_tokenization_enabled: item.is_pre_network_tokenization_enabled,
+            acquirer_configs: item.acquirer_config_map,
             is_iframe_redirection_enabled: item.is_iframe_redirection_enabled,
         })
     }
diff --git a/crates/router/src/workflows/attach_payout_account_workflow.rs b/crates/router/src/workflows/attach_payout_account_workflow.rs
index 910afe3166c..9704ce06d3d 100644
--- a/crates/router/src/workflows/attach_payout_account_workflow.rs
+++ b/crates/router/src/workflows/attach_payout_account_workflow.rs
@@ -53,9 +53,14 @@ impl ProcessTrackerWorkflow<SessionState> for AttachPayoutAccountWorkflow {
             merchant_account.clone(),
             key_store.clone(),
         )));
-        let mut payout_data =
-            payouts::make_payout_data(state, &merchant_context, None, &request, DEFAULT_LOCALE)
-                .await?;
+        let mut payout_data = Box::pin(payouts::make_payout_data(
+            state,
+            &merchant_context,
+            None,
+            &request,
+            DEFAULT_LOCALE,
+        ))
+        .await?;
 
         payouts::payouts_core(state, &merchant_context, &mut payout_data, None, None).await?;
 
diff --git a/crates/router/src/workflows/outgoing_webhook_retry.rs b/crates/router/src/workflows/outgoing_webhook_retry.rs
index 56265c788f7..d525763529e 100644
--- a/crates/router/src/workflows/outgoing_webhook_retry.rs
+++ b/crates/router/src/workflows/outgoing_webhook_retry.rs
@@ -542,13 +542,13 @@ async fn get_outgoing_webhook_content_and_event_type(
                 payout_models::PayoutActionRequest { payout_id },
             );
 
-            let payout_data = payouts::make_payout_data(
+            let payout_data = Box::pin(payouts::make_payout_data(
                 &state,
                 &merchant_context,
                 None,
                 &request,
                 DEFAULT_LOCALE,
-            )
+            ))
             .await?;
 
             let router_response =
diff --git a/crates/router_env/src/logger/types.rs b/crates/router_env/src/logger/types.rs
index 12fd6108b62..27ab6dd7c10 100644
--- a/crates/router_env/src/logger/types.rs
+++ b/crates/router_env/src/logger/types.rs
@@ -594,6 +594,7 @@ pub enum Flow {
     CloneConnector,
     ///Proxy Flow
     Proxy,
+    ProfileAcquirerCreate,
     /// ThreeDs Decision Rule Execute flow
     ThreeDsDecisionRuleExecute,
 }
diff --git a/migrations/2025-06-05-122346_add-acquirer-config-in-business-profile/down.sql b/migrations/2025-06-05-122346_add-acquirer-config-in-business-profile/down.sql
new file mode 100644
index 00000000000..01490869cff
--- /dev/null
+++ b/migrations/2025-06-05-122346_add-acquirer-config-in-business-profile/down.sql
@@ -0,0 +1,2 @@
+-- This file should undo anything in `up.sql`
+ALTER TABLE business_profile DROP COLUMN IF EXISTS acquirer_config_map;
\ No newline at end of file
diff --git a/migrations/2025-06-05-122346_add-acquirer-config-in-business-profile/up.sql b/migrations/2025-06-05-122346_add-acquirer-config-in-business-profile/up.sql
new file mode 100644
index 00000000000..ac326b3ca4f
--- /dev/null
+++ b/migrations/2025-06-05-122346_add-acquirer-config-in-business-profile/up.sql
@@ -0,0 +1,2 @@
+-- Your SQL goes here
+ALTER TABLE business_profile ADD COLUMN IF NOT EXISTS acquirer_config_map JSONB;
\ No newline at end of file

## Type of Change
<!-- Put an `x` in the boxes that apply -->
- [x] New feature

## Description
<!-- Describe your changes in detail -->
added merchant acquirer create and list module

### Additional Changes

- [ ] This PR modifies the API contract
- [x] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables

Add new field merchant_acquirer_ids in business_profile

This pull request introduces support for managing acquirer configurations and profile acquirer entities, including updates to the OpenAPI specification, the Rust codebase, and database schema. The changes enable the creation, storage, and retrieval of acquirer configuration data and profile acquirer entities, which are essential for linking merchant profiles to acquirer accounts.

### API Enhancements:
* Added a new endpoint `/profile_acquirers` for creating profile acquirers in `api-reference/openapi_spec.json`. Includes request and response schemas (`ProfileAcquirerCreate` and `ProfileAcquirerResponse`). [[1]](diffhunk://#diff-120d5ba664a56f45b6d881ccac78000f991d22e2909b5e45c83602c7dfab27cdR5960-R5999) [[2]](diffhunk://#diff-120d5ba664a56f45b6d881ccac78000f991d22e2909b5e45c83602c7dfab27cdR25396-R25513)
* Defined schemas for `AcquirerConfig` and `AcquirerConfigMap` to describe acquirer configurations. [[1]](diffhunk://#diff-120d5ba664a56f45b6d881ccac78000f991d22e2909b5e45c83602c7dfab27cdR6350-R6406) [[2]](diffhunk://#diff-120d5ba664a56f45b6d881ccac78000f991d22e2909b5e45c83602c7dfab27cdR26036-R26043)

### Rust Codebase Updates:
* Introduced `ProfileAcquirerCreate` and `ProfileAcquirerResponse` structs in the new `crates/api_models/src/profile_acquirer.rs` file for handling profile acquirer data.
* Added `AcquirerConfig` and `AcquirerConfigMap` structs in `crates/common_types/src/domain.rs` to represent acquirer configuration data.
* Implemented `ProfileAcquirerId` type in `crates/common_utils/src/id_type/profile_acquirer.rs` for unique identification of profile acquirers.

### Database Schema Changes:
* Updated `business_profile` table to include a new column `acquirer_config_map` for storing acquirer configuration data in JSON format. [[1]](diffhunk://#diff-b3de56db64ac930fe24b6b0acb45282191598a506d20732f70ef00192b4b18d5R231) [[2]](diffhunk://#diff-22fdeee3005db31c44a9d40cd43c5a244e77a74e17d2e227d4c0b376f133f37eR226)
* Modified `Profile` and `ProfileUpdateInternal` structs in `crates/diesel_models/src/business_profile.rs` to include `acquirer_config_map`. [[1]](diffhunk://#diff-9580ab8a5056970f087fa2af0a8de98dae6bf038ade612e3c996b88b23ae6e11R77) [[2]](diffhunk://#diff-9580ab8a5056970f087fa2af0a8de98dae6bf038ade612e3c996b88b23ae6e11R187) [[3]](diffhunk://#diff-9580ab8a5056970f087fa2af0a8de98dae6bf038ade612e3c996b88b23ae6e11R239)

### Event and Utility Enhancements:
* Added `ProfileAcquirer` as a new event type in `crates/common_utils/src/events.rs`.
* Implemented utility functions for generating and handling `ProfileAcquirerId`. [[1]](diffhunk://#diff-9bbc934a55fcf5282e0b0ba208a3722e9691ee71709d15a5c0d0958759280fa0R256-R262) [[2]](diffhunk://#diff-42f2c04d1e7d6eaf0534968a602f64eb00017fc3799f3426816fd59abae0145cR1-R41)

## Motivation and Context
<!--
Why is this change required? What problem does it solve?
If it fixes an open issue, please link to the issue here.

If you don't have an issue, we'd recommend starting with one first so the PR
can focus on the implementation (unless it is an obvious bug or documentation fix
that will have little conversation).
-->
Currently we donot have a table to store merchant acquirer information, have build an api to insert data for merchant acquirer into business profile table

## How did you test it?
<!--
Did you write an integration/unit/API test to verify the code changes?
Or did you test this change manually (provide relevant screenshots)?
-->
Create a merchant account

Once done create merchant_acquirer

Request

```shell
curl --location 'localhost:8080/profile_acquirer' \
--header 'Content-Type: application/json' \
--header 'api-key: dev_rDKEInoZiJlNIfJPYNuqBMC2EOJjegGylLbzRMDw6kmSxV0FztdYfLcSoWZD6ZsT' \
--data '{
  "acquirer_assigned_merchant_id": "ACQ1xwjnd23456",
  "merchant_name": "Demo Merchant",
  "merchant_country_code": "IN",
  "network": "Visa",
  "acquirer_bin": "400000",
  "acquirer_ica": "ICA98765",
  "acquirer_fraud_rate": 0.02,
  "profile_id": "pro_AFTXNDSW2mZadl5tEmqd"
}'
```

Response:

```shell
{
    "profile_acquirer_id": "pro_acq_ZlIC3dqlERLvrvLfXCUX",
    "acquirer_assigned_merchant_id": "ACQ1xwjnd23456",
    "merchant_name": "Demo Merchant",
    "merchant_country_code": "IN",
    "network": "Visa",
    "acquirer_bin": "400000",
    "acquirer_ica": "ICA98765",
    "acquirer_fraud_rate": 0.02,
    "profile_id": "pro_B9IE9uHjgRVKXHp9MSqG",
    "created_at": "2025-05-27T11:43:15.477Z"
}
```

try hitting the api with same sample set

Response:shell

```
{
    "error": {
        "type": "invalid_request",
        "message": "Profile acquirer configuration with id pro_acq_vhDNwqBvqM6BqbCZ8FJa already exists.",
        "code": "IR_38"
    }
}
```
Business profile schema details

```shell
                                                   Table "public.business_profile"
                        Column                         |            Type             | Collation | Nullable |         Default
-------------------------------------------------------+-----------------------------+-----------+----------+-------------------------
 profile_id                                            | character varying(64)       |           | not null |
 merchant_id                                           | character varying(64)       |           | not null |
 profile_name                                          | character varying(64)       |           | not null |
 created_at                                            | timestamp without time zone |           | not null |
 modified_at                                           | timestamp without time zone |           | not null |
 return_url                                            | text                        |           |          |
 enable_payment_response_hash                          | boolean                     |           | not null | true
 payment_response_hash_key                             | character varying(255)      |           |          | NULL::character varying
 redirect_to_merchant_with_http_post                   | boolean                     |           | not null | false
 webhook_details                                       | json                        |           |          |
 metadata                                              | json                        |           |          |
 routing_algorithm                                     | json                        |           |          |
 intent_fulfillment_time                               | bigint                      |           |          |
 frm_routing_algorithm                                 | jsonb                       |           |          |
 payout_routing_algorithm                              | jsonb                       |           |          |
 is_recon_enabled                                      | boolean                     |           | not null | false
 applepay_verified_domains                             | text[]                      |           |          |
 payment_link_config                                   | jsonb                       |           |          |
 session_expiry                                        | bigint                      |           |          |
 authentication_connector_details                      | jsonb                       |           |          |
 payout_link_config                                    | jsonb                       |           |          |
 is_extended_card_info_enabled                         | boolean                     |           |          | false
 extended_card_info_config                             | jsonb                       |           |          |
 is_connector_agnostic_mit_enabled                     | boolean                     |           |          | false
 use_billing_as_payment_method_billing                 | boolean                     |           |          | true
 collect_shipping_details_from_wallet_connector        | boolean                     |           |          | false
 collect_billing_details_from_wallet_connector         | boolean                     |           |          | false
 outgoing_webhook_custom_http_headers                  | bytea                       |           |          |
 always_collect_billing_details_from_wallet_connector  | boolean                     |           |          | false
 always_collect_shipping_details_from_wallet_connector | boolean                     |           |          | false
 tax_connector_id                                      | character varying(64)       |           |          |
 is_tax_connector_enabled                              | boolean                     |           |          |
 version                                               | "ApiVersion"                |           | not null | 'v1'::"ApiVersion"
 dynamic_routing_algorithm                             | json                        |           |          |
 is_network_tokenization_enabled                       | boolean                     |           | not null | false
 is_auto_retries_enabled                               | boolean                     |           |          |
 max_auto_retries_enabled                              | smallint                    |           |          |
 always_request_extended_authorization                 | boolean                     |           |          |
 is_click_to_pay_enabled                               | boolean                     |           | not null | false
 authentication_product_ids                            | jsonb                       |           |          |
 card_testing_guard_config                             | jsonb                       |           |          |
 card_testing_secret_key                               | bytea                       |           |          |
 is_clear_pan_retries_enabled                          | boolean                     |           | not null | false
 force_3ds_challenge                                   | boolean                     |           |          | false
 is_debit_routing_enabled                              | boolean                     |           | not null | false
 merchant_business_country                             | "CountryAlpha2"             |           |          |
 id                                                    | character varying(64)       |           |          |
 is_iframe_redirection_enabled                         | boolean                     |           |          |
 is_pre_network_tokenization_enabled                   | boolean                     |           |          |
 three_ds_decision_rule_algorithm                      | jsonb                       |           |          |
 acquirer_config_map                                   | jsonb                       |           |          |
Indexes:
    "business_profile_pkey" PRIMARY KEY, btree (profile_id)
```


List profile acquirer account -- do business profile retrieve

```shell
curl --location 'localhost:8080/account/sahkal/business_profile/pro_RUyg7qT8yMzgfQpTqqm8' \
--header 'api-key: dev_dzO6ovCaZazaULNtb0AJxDIfCX67yQUQGYP190ZKX8KCd9WYoFhFIFRxVB8B5w6Q'
```

Response

```shell
{
    "merchant_id": "sahkal",
    "profile_id": "pro_RUyg7qT8yMzgfQpTqqm8",
    "profile_name": "US_default",
    "return_url": "https://google.com/success",
    "enable_payment_response_hash": true,
    "payment_response_hash_key": "U9qcRdTlSXQc4cnsaEXMEpuiPVgw4RmekxfLjNznZjUt83u2tav6e6XYIdFZA9dw",
    "redirect_to_merchant_with_http_post": false,
    "webhook_details": {
        "webhook_version": "1.0.1",
        "webhook_username": "ekart_retail",
        "webhook_password": "password_ekart@123",
        "webhook_url": null,
        "payment_created_enabled": true,
        "payment_succeeded_enabled": true,
        "payment_failed_enabled": true
    },
    "metadata": null,
    "routing_algorithm": null,
    "intent_fulfillment_time": 900,
    "frm_routing_algorithm": null,
    "payout_routing_algorithm": null,
    "applepay_verified_domains": null,
    "session_expiry": 900,
    "payment_link_config": null,
    "authentication_connector_details": null,
    "use_billing_as_payment_method_billing": true,
    "extended_card_info_config": null,
    "collect_shipping_details_from_wallet_connector": false,
    "collect_billing_details_from_wallet_connector": false,
    "always_collect_shipping_details_from_wallet_connector": false,
    "always_collect_billing_details_from_wallet_connector": false,
    "is_connector_agnostic_mit_enabled": false,
    "payout_link_config": null,
    "outgoing_webhook_custom_http_headers": null,
    "tax_connector_id": null,
    "is_tax_connector_enabled": false,
    "is_network_tokenization_enabled": false,
    "is_auto_retries_enabled": false,
    "max_auto_retries_enabled": null,
    "always_request_extended_authorization": null,
    "is_click_to_pay_enabled": false,
    "authentication_product_ids": null,
    "card_testing_guard_config": {
        "card_ip_blocking_status": "disabled",
        "card_ip_blocking_threshold": 3,
        "guest_user_card_blocking_status": "disabled",
        "guest_user_card_blocking_threshold": 10,
        "customer_id_blocking_status": "disabled",
        "customer_id_blocking_threshold": 5,
        "card_testing_guard_expiry": 3600
    },
    "is_clear_pan_retries_enabled": false,
    "force_3ds_challenge": false,
    "is_debit_routing_enabled": false,
    "merchant_business_country": null,
    "is_pre_network_tokenization_enabled": false,
    "acquirer_configs": {
        "pro_acq_jkn6Di8kIqBVrmICSEYU": {
            "acquirer_assigned_merchant_id": "fqwcqsqqwacccwwwec",
            "merchant_name": "Demo Merchant",
            "merchant_country_code": "US",
            "network": "Visa",
            "acquirer_bin": "400000",
            "acquirer_ica": null,
            "acquirer_fraud_rate": 0.06
        },
        "pro_acq_bbNCgQibI8K1Xr6Cv3fu": {
            "acquirer_assigned_merchant_id": "fqwcqsqqwacdqwdwqdccwwwec",
            "merchant_name": "Demo Merchant",
            "merchant_country_code": "US",
            "network": "Visa",
            "acquirer_bin": "400000",
            "acquirer_ica": null,
            "acquirer_fraud_rate": 0.06
        }
    }
}
```


## Checklist
<!-- Put an `x` in the boxes that apply -->

- [x] I formatted the code `cargo +nightly fmt --all`
- [x] I addressed lints thrown by `cargo clippy`
- [x] I reviewed the submitted code
- [ ] I added unit tests for my changes where possible


<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Added a new API endpoint to create Profile Acquirers linked to business profiles.
  - Enabled profiles to store multiple acquirer configurations with detailed attributes like merchant ID, country code, network, BIN, ICA, and fraud rate.
- **Database**
  - Introduced a new JSONB column to store acquirer configuration maps within business profiles.
- **API Documentation**
  - Updated OpenAPI specs to document new Profile Acquirer endpoints and related schemas.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->