Bug: add `merchant_category_code` in business profile



Add support to accept `merchant_category_code` as input in the business profile. This is the four-digit code assigned based on business type to determine processing fees and risk level. This code can be used to make various decision during a payment flow. One such use case is network interchange fee calculation in debit routing.
diff --git a/api-reference-v2/openapi_spec.json b/api-reference-v2/openapi_spec.json
index 2e337c1f560..f1260390795 100644
--- a/api-reference-v2/openapi_spec.json
+++ b/api-reference-v2/openapi_spec.json
@@ -13195,6 +13195,18 @@
         },
         "additionalProperties": false
       },
+      "MerchantCategoryCode": {
+        "type": "string",
+        "enum": [
+          "5411",
+          "7011",
+          "0763",
+          "8111",
+          "5021",
+          "4816",
+          "5661"
+        ]
+      },
       "MerchantConnectorAccountFeatureMetadata": {
         "type": "object",
         "description": "Feature metadata for merchant connector account",
@@ -20977,6 +20989,14 @@
               }
             ],
             "nullable": true
+          },
+          "merchant_category_code": {
+            "allOf": [
+              {
+                "$ref": "#/components/schemas/MerchantCategoryCode"
+              }
+            ],
+            "nullable": true
           }
         },
         "additionalProperties": false
@@ -21246,6 +21266,14 @@
               }
             ],
             "nullable": true
+          },
+          "merchant_category_code": {
+            "allOf": [
+              {
+                "$ref": "#/components/schemas/MerchantCategoryCode"
+              }
+            ],
+            "nullable": true
           }
         }
       },
diff --git a/crates/api_models/src/admin.rs b/crates/api_models/src/admin.rs
index 07f3e2431fa..d30abfe813f 100644
--- a/crates/api_models/src/admin.rs
+++ b/crates/api_models/src/admin.rs
@@ -2121,6 +2121,10 @@ pub struct ProfileCreate {
 
     /// Indicates if pre network tokenization is enabled or not
     pub is_pre_network_tokenization_enabled: Option<bool>,
+
+    /// Four-digit code assigned based on business type to determine processing fees and risk level
+    #[schema(value_type = Option<MerchantCategoryCode>, example = "5411")]
+    pub merchant_category_code: Option<api_enums::MerchantCategoryCode>,
 }
 
 #[nutype::nutype(
@@ -2263,6 +2267,10 @@ pub struct ProfileCreate {
 
     /// External Vault Connector Details
     pub external_vault_connector_details: Option<ExternalVaultConnectorDetails>,
+
+    /// Four-digit code assigned based on business type to determine processing fees and risk level
+    #[schema(value_type = Option<MerchantCategoryCode>, example = "5411")]
+    pub merchant_category_code: Option<api_enums::MerchantCategoryCode>,
 }
 
 #[cfg(feature = "v1")]
@@ -2434,6 +2442,10 @@ pub struct ProfileResponse {
     /// Indicates if the redirection has to open in the iframe
     #[schema(example = false)]
     pub is_iframe_redirection_enabled: Option<bool>,
+
+    /// Four-digit code assigned based on business type to determine processing fees and risk level
+    #[schema(value_type = Option<MerchantCategoryCode>, example = "5411")]
+    pub merchant_category_code: Option<api_enums::MerchantCategoryCode>,
 }
 
 #[cfg(feature = "v2")]
@@ -2584,6 +2596,10 @@ pub struct ProfileResponse {
 
     /// External Vault Connector Details
     pub external_vault_connector_details: Option<ExternalVaultConnectorDetails>,
+
+    /// Four-digit code assigned based on business type to determine processing fees and risk level
+    #[schema(value_type = Option<MerchantCategoryCode>, example = "5411")]
+    pub merchant_category_code: Option<api_enums::MerchantCategoryCode>,
 }
 
 #[cfg(feature = "v1")]
@@ -2740,6 +2756,10 @@ pub struct ProfileUpdate {
     /// Indicates if pre network tokenization is enabled or not
     #[schema(default = false, example = false)]
     pub is_pre_network_tokenization_enabled: Option<bool>,
+
+    /// Four-digit code assigned based on business type to determine processing fees and risk level
+    #[schema(value_type = Option<MerchantCategoryCode>, example = "5411")]
+    pub merchant_category_code: Option<api_enums::MerchantCategoryCode>,
 }
 
 #[cfg(feature = "v2")]
@@ -2872,6 +2892,10 @@ pub struct ProfileUpdate {
 
     /// External Vault Connector Details
     pub external_vault_connector_details: Option<ExternalVaultConnectorDetails>,
+
+    /// Four-digit code assigned based on business type to determine processing fees and risk level
+    #[schema(value_type = Option<MerchantCategoryCode>, example = "5411")]
+    pub merchant_category_code: Option<api_enums::MerchantCategoryCode>,
 }
 
 #[derive(Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)]
diff --git a/crates/api_models/src/open_router.rs b/crates/api_models/src/open_router.rs
index 08607e1469b..33719e8a41b 100644
--- a/crates/api_models/src/open_router.rs
+++ b/crates/api_models/src/open_router.rs
@@ -107,7 +107,7 @@ impl TryFrom<(payment_methods::CoBadgedCardData, String)> for DebitRoutingReques
 
 #[derive(Debug, Clone, Serialize, Deserialize)]
 pub struct CoBadgedCardRequest {
-    pub merchant_category_code: common_enums::MerchantCategoryCode,
+    pub merchant_category_code: common_enums::DecisionEngineMerchantCategoryCode,
     pub acquirer_country: common_enums::CountryAlpha2,
     pub co_badged_card_data: Option<DebitRoutingRequestData>,
 }
diff --git a/crates/common_enums/src/enums.rs b/crates/common_enums/src/enums.rs
index 893a3b7dafa..5daabd0bc78 100644
--- a/crates/common_enums/src/enums.rs
+++ b/crates/common_enums/src/enums.rs
@@ -2412,7 +2412,7 @@ pub enum CardType {
 
 #[derive(Debug, Clone, Serialize, Deserialize, strum::EnumString, strum::Display)]
 #[serde(rename_all = "snake_case")]
-pub enum MerchantCategoryCode {
+pub enum DecisionEngineMerchantCategoryCode {
     #[serde(rename = "merchant_category_code_0001")]
     Mcc0001,
 }
@@ -2515,6 +2515,98 @@ pub enum DisputeStatus {
     DisputeLost,
 }
 
+#[derive(
+    Clone,
+    Copy,
+    Debug,
+    Eq,
+    Hash,
+    PartialEq,
+    serde::Deserialize,
+    serde::Serialize,
+    strum::Display,
+    strum::EnumString,
+    strum::EnumIter,
+    strum::VariantNames,
+    ToSchema,
+)]
+pub enum MerchantCategory {
+    #[serde(rename = "Grocery Stores, Supermarkets (5411)")]
+    GroceryStoresSupermarkets,
+    #[serde(rename = "Lodging-Hotels, Motels, Resorts-not elsewhere classified (7011)")]
+    LodgingHotelsMotelsResorts,
+    #[serde(rename = "Agricultural Cooperatives (0763)")]
+    AgriculturalCooperatives,
+    #[serde(rename = "Attorneys, Legal Services (8111)")]
+    AttorneysLegalServices,
+    #[serde(rename = "Office and Commercial Furniture (5021)")]
+    OfficeAndCommercialFurniture,
+    #[serde(rename = "Computer Network/Information Services (4816)")]
+    ComputerNetworkInformationServices,
+    #[serde(rename = "Shoe Stores (5661)")]
+    ShoeStores,
+}
+
+#[derive(
+    Clone,
+    Copy,
+    Debug,
+    Eq,
+    Hash,
+    PartialEq,
+    serde::Deserialize,
+    serde::Serialize,
+    strum::Display,
+    strum::EnumString,
+    strum::EnumIter,
+    strum::VariantNames,
+    ToSchema,
+)]
+#[router_derive::diesel_enum(storage_type = "text")]
+pub enum MerchantCategoryCode {
+    #[serde(rename = "5411")]
+    #[strum(serialize = "5411")]
+    Mcc5411,
+    #[serde(rename = "7011")]
+    #[strum(serialize = "7011")]
+    Mcc7011,
+    #[serde(rename = "0763")]
+    #[strum(serialize = "0763")]
+    Mcc0763,
+    #[serde(rename = "8111")]
+    #[strum(serialize = "8111")]
+    Mcc8111,
+    #[serde(rename = "5021")]
+    #[strum(serialize = "5021")]
+    Mcc5021,
+    #[serde(rename = "4816")]
+    #[strum(serialize = "4816")]
+    Mcc4816,
+    #[serde(rename = "5661")]
+    #[strum(serialize = "5661")]
+    Mcc5661,
+}
+
+impl MerchantCategoryCode {
+    pub fn to_merchant_category_name(&self) -> MerchantCategory {
+        match self {
+            Self::Mcc5411 => MerchantCategory::GroceryStoresSupermarkets,
+            Self::Mcc7011 => MerchantCategory::LodgingHotelsMotelsResorts,
+            Self::Mcc0763 => MerchantCategory::AgriculturalCooperatives,
+            Self::Mcc8111 => MerchantCategory::AttorneysLegalServices,
+            Self::Mcc5021 => MerchantCategory::OfficeAndCommercialFurniture,
+            Self::Mcc4816 => MerchantCategory::ComputerNetworkInformationServices,
+            Self::Mcc5661 => MerchantCategory::ShoeStores,
+        }
+    }
+}
+
+#[derive(serde::Serialize, serde::Deserialize, Clone, Debug, PartialEq)]
+pub struct MerchantCategoryCodeWithName {
+    pub code: MerchantCategoryCode,
+    pub name: MerchantCategory,
+}
+
 #[derive(
     Clone,
     Debug,
diff --git a/crates/diesel_models/src/business_profile.rs b/crates/diesel_models/src/business_profile.rs
index a93bab30a49..e2543e3b431 100644
--- a/crates/diesel_models/src/business_profile.rs
+++ b/crates/diesel_models/src/business_profile.rs
@@ -75,6 +75,7 @@ pub struct Profile {
     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>,
+    pub merchant_category_code: Option<common_enums::MerchantCategoryCode>,
 }
 
 #[cfg(feature = "v1")]
@@ -130,6 +131,7 @@ pub struct ProfileNew {
     pub id: Option<common_utils::id_type::ProfileId>,
     pub is_iframe_redirection_enabled: Option<bool>,
     pub is_pre_network_tokenization_enabled: Option<bool>,
+    pub merchant_category_code: Option<common_enums::MerchantCategoryCode>,
 }
 
 #[cfg(feature = "v1")]
@@ -185,6 +187,7 @@ pub struct ProfileUpdateInternal {
     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>,
+    pub merchant_category_code: Option<common_enums::MerchantCategoryCode>,
 }
 
 #[cfg(feature = "v1")]
@@ -237,6 +240,7 @@ impl ProfileUpdateInternal {
             is_pre_network_tokenization_enabled,
             three_ds_decision_rule_algorithm,
             acquirer_config_map,
+            merchant_category_code,
         } = self;
         Profile {
             profile_id: source.profile_id,
@@ -320,6 +324,7 @@ impl ProfileUpdateInternal {
             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),
+            merchant_category_code: merchant_category_code.or(source.merchant_category_code),
         }
     }
 }
@@ -381,6 +386,7 @@ pub struct Profile {
     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 merchant_category_code: Option<common_enums::MerchantCategoryCode>,
     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>,
@@ -452,6 +458,7 @@ pub struct ProfileNew {
     pub is_clear_pan_retries_enabled: Option<bool>,
     pub is_debit_routing_enabled: bool,
     pub merchant_business_country: Option<common_enums::CountryAlpha2>,
+    pub merchant_category_code: Option<common_enums::MerchantCategoryCode>,
     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>,
@@ -510,6 +517,7 @@ pub struct ProfileUpdateInternal {
     pub is_clear_pan_retries_enabled: Option<bool>,
     pub is_debit_routing_enabled: Option<bool>,
     pub merchant_business_country: Option<common_enums::CountryAlpha2>,
+    pub merchant_category_code: Option<common_enums::MerchantCategoryCode>,
     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>,
@@ -578,6 +586,7 @@ impl ProfileUpdateInternal {
             is_iframe_redirection_enabled,
             is_external_vault_enabled,
             external_vault_connector_details,
+            merchant_category_code,
         } = self;
         Profile {
             id: source.id,
@@ -671,6 +680,7 @@ impl ProfileUpdateInternal {
                 .or(source.external_vault_connector_details),
             three_ds_decision_rule_algorithm: None,
             acquirer_config_map: None,
+            merchant_category_code: merchant_category_code.or(source.merchant_category_code),
         }
     }
 }
diff --git a/crates/diesel_models/src/schema.rs b/crates/diesel_models/src/schema.rs
index 4e93ecab944..522ad271be9 100644
--- a/crates/diesel_models/src/schema.rs
+++ b/crates/diesel_models/src/schema.rs
@@ -229,6 +229,8 @@ diesel::table! {
         is_pre_network_tokenization_enabled -> Nullable<Bool>,
         three_ds_decision_rule_algorithm -> Nullable<Jsonb>,
         acquirer_config_map -> Nullable<Jsonb>,
+        #[max_length = 16]
+        merchant_category_code -> Nullable<Varchar>,
     }
 }
 
diff --git a/crates/diesel_models/src/schema_v2.rs b/crates/diesel_models/src/schema_v2.rs
index 882c620d9fb..6ea3b49bb0c 100644
--- a/crates/diesel_models/src/schema_v2.rs
+++ b/crates/diesel_models/src/schema_v2.rs
@@ -224,6 +224,8 @@ diesel::table! {
         is_iframe_redirection_enabled -> Nullable<Bool>,
         three_ds_decision_rule_algorithm -> Nullable<Jsonb>,
         acquirer_config_map -> Nullable<Jsonb>,
+        #[max_length = 16]
+        merchant_category_code -> Nullable<Varchar>,
         #[max_length = 64]
         routing_algorithm_id -> Nullable<Varchar>,
         order_fulfillment_time -> Nullable<Int8>,
diff --git a/crates/euclid_wasm/src/lib.rs b/crates/euclid_wasm/src/lib.rs
index 6e8c327b7e4..25d1da385ad 100644
--- a/crates/euclid_wasm/src/lib.rs
+++ b/crates/euclid_wasm/src/lib.rs
@@ -34,7 +34,7 @@ use wasm_bindgen::prelude::*;
 use crate::utils::JsResultExt;
 type JsResult = Result<JsValue, JsValue>;
 use api_models::payment_methods::CountryCodeWithName;
-use common_enums::CountryAlpha2;
+use common_enums::{CountryAlpha2, MerchantCategoryCode, MerchantCategoryCodeWithName};
 use strum::IntoEnumIterator;
 
 struct SeedData {
@@ -91,6 +91,22 @@ pub fn get_two_letter_country_code() -> JsResult {
     Ok(serde_wasm_bindgen::to_value(&country_code_with_name)?)
 }
 
+/// This function can be used by the frontend to get all the merchant category codes
+/// along with their names.
+#[wasm_bindgen(js_name=getMerchantCategoryCodeWithName)]
+pub fn get_merchant_category_code_with_name() -> JsResult {
+    let merchant_category_codes_with_name = MerchantCategoryCode::iter()
+        .map(|mcc_value| MerchantCategoryCodeWithName {
+            code: mcc_value,
+            name: mcc_value.to_merchant_category_name(),
+        })
+        .collect::<Vec<_>>();
+
+    Ok(serde_wasm_bindgen::to_value(
+        &merchant_category_codes_with_name,
+    )?)
+}
+
 /// This function can be used by the frontend to provide the WASM with information about
 /// all the merchant's connector accounts. The input argument is a vector of all the merchant's
 /// connector accounts from the API.
diff --git a/crates/hyperswitch_domain_models/src/business_profile.rs b/crates/hyperswitch_domain_models/src/business_profile.rs
index 6c95af4f149..93ed2af4945 100644
--- a/crates/hyperswitch_domain_models/src/business_profile.rs
+++ b/crates/hyperswitch_domain_models/src/business_profile.rs
@@ -77,6 +77,7 @@ pub struct Profile {
     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>,
+    pub merchant_category_code: Option<api_enums::MerchantCategoryCode>,
 }
 
 #[cfg(feature = "v1")]
@@ -130,6 +131,7 @@ pub struct ProfileSetter {
     pub merchant_business_country: Option<api_enums::CountryAlpha2>,
     pub is_iframe_redirection_enabled: Option<bool>,
     pub is_pre_network_tokenization_enabled: bool,
+    pub merchant_category_code: Option<api_enums::MerchantCategoryCode>,
 }
 
 #[cfg(feature = "v1")]
@@ -190,6 +192,7 @@ impl From<ProfileSetter> for Profile {
             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,
+            merchant_category_code: value.merchant_category_code,
         }
     }
 }
@@ -250,6 +253,7 @@ pub struct ProfileGeneralUpdate {
     pub merchant_business_country: Option<api_enums::CountryAlpha2>,
     pub is_iframe_redirection_enabled: Option<bool>,
     pub is_pre_network_tokenization_enabled: Option<bool>,
+    pub merchant_category_code: Option<api_enums::MerchantCategoryCode>,
 }
 
 #[cfg(feature = "v1")]
@@ -329,6 +333,7 @@ impl From<ProfileUpdate> for ProfileUpdateInternal {
                     merchant_business_country,
                     is_iframe_redirection_enabled,
                     is_pre_network_tokenization_enabled,
+                    merchant_category_code,
                 } = *update;
 
                 Self {
@@ -379,6 +384,7 @@ impl From<ProfileUpdate> for ProfileUpdateInternal {
                     is_pre_network_tokenization_enabled,
                     three_ds_decision_rule_algorithm: None,
                     acquirer_config_map: None,
+                    merchant_category_code,
                 }
             }
             ProfileUpdate::RoutingAlgorithmUpdate {
@@ -432,6 +438,7 @@ impl From<ProfileUpdate> for ProfileUpdateInternal {
                 is_pre_network_tokenization_enabled: None,
                 three_ds_decision_rule_algorithm,
                 acquirer_config_map: None,
+                merchant_category_code: None,
             },
             ProfileUpdate::DynamicRoutingAlgorithmUpdate {
                 dynamic_routing_algorithm,
@@ -482,6 +489,7 @@ impl From<ProfileUpdate> for ProfileUpdateInternal {
                 is_pre_network_tokenization_enabled: None,
                 three_ds_decision_rule_algorithm: None,
                 acquirer_config_map: None,
+                merchant_category_code: None,
             },
             ProfileUpdate::ExtendedCardInfoUpdate {
                 is_extended_card_info_enabled,
@@ -532,6 +540,7 @@ impl From<ProfileUpdate> for ProfileUpdateInternal {
                 is_pre_network_tokenization_enabled: None,
                 three_ds_decision_rule_algorithm: None,
                 acquirer_config_map: None,
+                merchant_category_code: None,
             },
             ProfileUpdate::ConnectorAgnosticMitUpdate {
                 is_connector_agnostic_mit_enabled,
@@ -582,6 +591,7 @@ impl From<ProfileUpdate> for ProfileUpdateInternal {
                 is_pre_network_tokenization_enabled: None,
                 three_ds_decision_rule_algorithm: None,
                 acquirer_config_map: None,
+                merchant_category_code: None,
             },
             ProfileUpdate::NetworkTokenizationUpdate {
                 is_network_tokenization_enabled,
@@ -632,6 +642,7 @@ impl From<ProfileUpdate> for ProfileUpdateInternal {
                 is_pre_network_tokenization_enabled: None,
                 three_ds_decision_rule_algorithm: None,
                 acquirer_config_map: None,
+                merchant_category_code: None,
             },
             ProfileUpdate::CardTestingSecretKeyUpdate {
                 card_testing_secret_key,
@@ -682,6 +693,7 @@ impl From<ProfileUpdate> for ProfileUpdateInternal {
                 is_pre_network_tokenization_enabled: None,
                 three_ds_decision_rule_algorithm: None,
                 acquirer_config_map: None,
+                merchant_category_code: None,
             },
             ProfileUpdate::AcquirerConfigMapUpdate {
                 acquirer_config_map,
@@ -732,6 +744,7 @@ impl From<ProfileUpdate> for ProfileUpdateInternal {
                 is_pre_network_tokenization_enabled: None,
                 three_ds_decision_rule_algorithm: None,
                 acquirer_config_map,
+                merchant_category_code: None,
             },
         }
     }
@@ -802,6 +815,7 @@ impl super::behaviour::Conversion for Profile {
             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,
+            merchant_category_code: self.merchant_category_code,
         })
     }
 
@@ -898,6 +912,7 @@ impl super::behaviour::Conversion for Profile {
                     .unwrap_or(false),
                 three_ds_decision_rule_algorithm: item.three_ds_decision_rule_algorithm,
                 acquirer_config_map: item.acquirer_config_map,
+                merchant_category_code: item.merchant_category_code,
             })
         }
         .await
@@ -961,6 +976,7 @@ impl super::behaviour::Conversion for Profile {
             merchant_business_country: self.merchant_business_country,
             is_iframe_redirection_enabled: self.is_iframe_redirection_enabled,
             is_pre_network_tokenization_enabled: Some(self.is_pre_network_tokenization_enabled),
+            merchant_category_code: self.merchant_category_code,
         })
     }
 }
@@ -1020,6 +1036,7 @@ pub struct Profile {
     pub is_iframe_redirection_enabled: Option<bool>,
     pub is_external_vault_enabled: Option<bool>,
     pub external_vault_connector_details: Option<ExternalVaultConnectorDetails>,
+    pub merchant_category_code: Option<api_enums::MerchantCategoryCode>,
 }
 
 #[cfg(feature = "v2")]
@@ -1075,6 +1092,7 @@ pub struct ProfileSetter {
     pub is_iframe_redirection_enabled: Option<bool>,
     pub is_external_vault_enabled: Option<bool>,
     pub external_vault_connector_details: Option<ExternalVaultConnectorDetails>,
+    pub merchant_category_code: Option<api_enums::MerchantCategoryCode>,
 }
 
 #[cfg(feature = "v2")]
@@ -1135,6 +1153,7 @@ impl From<ProfileSetter> for Profile {
             is_iframe_redirection_enabled: value.is_iframe_redirection_enabled,
             is_external_vault_enabled: value.is_external_vault_enabled,
             external_vault_connector_details: value.external_vault_connector_details,
+            merchant_category_code: value.merchant_category_code,
         }
     }
 }
@@ -1214,6 +1233,7 @@ pub struct ProfileGeneralUpdate {
     pub is_iframe_redirection_enabled: Option<bool>,
     pub is_external_vault_enabled: Option<bool>,
     pub external_vault_connector_details: Option<ExternalVaultConnectorDetails>,
+    pub merchant_category_code: Option<api_enums::MerchantCategoryCode>,
 }
 
 #[cfg(feature = "v2")]
@@ -1292,6 +1312,7 @@ impl From<ProfileUpdate> for ProfileUpdateInternal {
                     is_iframe_redirection_enabled,
                     is_external_vault_enabled,
                     external_vault_connector_details,
+                    merchant_category_code,
                 } = *update;
                 Self {
                     profile_name,
@@ -1343,6 +1364,7 @@ impl From<ProfileUpdate> for ProfileUpdateInternal {
                     is_iframe_redirection_enabled: None,
                     is_external_vault_enabled,
                     external_vault_connector_details,
+                    merchant_category_code,
                 }
             }
             ProfileUpdate::RoutingAlgorithmUpdate {
@@ -1397,6 +1419,7 @@ impl From<ProfileUpdate> for ProfileUpdateInternal {
                 is_iframe_redirection_enabled: None,
                 is_external_vault_enabled: None,
                 external_vault_connector_details: None,
+                merchant_category_code: None,
             },
             ProfileUpdate::ExtendedCardInfoUpdate {
                 is_extended_card_info_enabled,
@@ -1449,6 +1472,7 @@ impl From<ProfileUpdate> for ProfileUpdateInternal {
                 is_iframe_redirection_enabled: None,
                 is_external_vault_enabled: None,
                 external_vault_connector_details: None,
+                merchant_category_code: None,
             },
             ProfileUpdate::ConnectorAgnosticMitUpdate {
                 is_connector_agnostic_mit_enabled,
@@ -1501,6 +1525,7 @@ impl From<ProfileUpdate> for ProfileUpdateInternal {
                 is_iframe_redirection_enabled: None,
                 is_external_vault_enabled: None,
                 external_vault_connector_details: None,
+                merchant_category_code: None,
             },
             ProfileUpdate::DefaultRoutingFallbackUpdate {
                 default_fallback_routing,
@@ -1553,6 +1578,7 @@ impl From<ProfileUpdate> for ProfileUpdateInternal {
                 is_iframe_redirection_enabled: None,
                 is_external_vault_enabled: None,
                 external_vault_connector_details: None,
+                merchant_category_code: None,
             },
             ProfileUpdate::NetworkTokenizationUpdate {
                 is_network_tokenization_enabled,
@@ -1605,6 +1631,7 @@ impl From<ProfileUpdate> for ProfileUpdateInternal {
                 is_iframe_redirection_enabled: None,
                 is_external_vault_enabled: None,
                 external_vault_connector_details: None,
+                merchant_category_code: None,
             },
             ProfileUpdate::CollectCvvDuringPaymentUpdate {
                 should_collect_cvv_during_payment,
@@ -1657,6 +1684,7 @@ impl From<ProfileUpdate> for ProfileUpdateInternal {
                 is_iframe_redirection_enabled: None,
                 is_external_vault_enabled: None,
                 external_vault_connector_details: None,
+                merchant_category_code: None,
             },
             ProfileUpdate::DecisionManagerRecordUpdate {
                 three_ds_decision_manager_config,
@@ -1709,6 +1737,7 @@ impl From<ProfileUpdate> for ProfileUpdateInternal {
                 is_iframe_redirection_enabled: None,
                 is_external_vault_enabled: None,
                 external_vault_connector_details: None,
+                merchant_category_code: None,
             },
             ProfileUpdate::CardTestingSecretKeyUpdate {
                 card_testing_secret_key,
@@ -1761,6 +1790,7 @@ impl From<ProfileUpdate> for ProfileUpdateInternal {
                 is_iframe_redirection_enabled: None,
                 is_external_vault_enabled: None,
                 external_vault_connector_details: None,
+                merchant_category_code: None,
             },
             ProfileUpdate::RevenueRecoveryAlgorithmUpdate {
                 revenue_recovery_retry_algorithm_type,
@@ -1814,6 +1844,7 @@ impl From<ProfileUpdate> for ProfileUpdateInternal {
                 is_iframe_redirection_enabled: None,
                 is_external_vault_enabled: None,
                 external_vault_connector_details: None,
+                merchant_category_code: None,
             },
         }
     }
@@ -1890,6 +1921,7 @@ impl super::behaviour::Conversion for Profile {
             external_vault_connector_details: self.external_vault_connector_details,
             three_ds_decision_rule_algorithm: None,
             acquirer_config_map: None,
+            merchant_category_code: self.merchant_category_code,
         })
     }
 
@@ -1983,6 +2015,7 @@ impl super::behaviour::Conversion for Profile {
                 is_iframe_redirection_enabled: item.is_iframe_redirection_enabled,
                 is_external_vault_enabled: item.is_external_vault_enabled,
                 external_vault_connector_details: item.external_vault_connector_details,
+                merchant_category_code: item.merchant_category_code,
             })
         }
         .await
@@ -2051,6 +2084,7 @@ impl super::behaviour::Conversion for Profile {
             is_iframe_redirection_enabled: self.is_iframe_redirection_enabled,
             is_external_vault_enabled: self.is_external_vault_enabled,
             external_vault_connector_details: self.external_vault_connector_details,
+            merchant_category_code: self.merchant_category_code,
         })
     }
 }
diff --git a/crates/openapi/src/openapi.rs b/crates/openapi/src/openapi.rs
index 171f37cca19..6738824b054 100644
--- a/crates/openapi/src/openapi.rs
+++ b/crates/openapi/src/openapi.rs
@@ -324,6 +324,7 @@ Never share your secret api keys. Keep them guarded and secure.
         api_models::enums::BankType,
         api_models::enums::BankHolderType,
         api_models::enums::CardNetwork,
+        api_models::enums::MerchantCategoryCode,
         api_models::enums::DisputeStage,
         api_models::enums::DisputeStatus,
         api_models::enums::CountryAlpha2,
diff --git a/crates/openapi/src/openapi_v2.rs b/crates/openapi/src/openapi_v2.rs
index 9a624c12a90..5b5ed7a83e4 100644
--- a/crates/openapi/src/openapi_v2.rs
+++ b/crates/openapi/src/openapi_v2.rs
@@ -285,6 +285,7 @@ Never share your secret api keys. Keep them guarded and secure.
         api_models::enums::BankType,
         api_models::enums::BankHolderType,
         api_models::enums::CardNetwork,
+        api_models::enums::MerchantCategoryCode,
         api_models::enums::TokenDataType,
         api_models::enums::DisputeStage,
         api_models::enums::DisputeStatus,
diff --git a/crates/router/src/core/admin.rs b/crates/router/src/core/admin.rs
index b8d24573c34..be009c127df 100644
--- a/crates/router/src/core/admin.rs
+++ b/crates/router/src/core/admin.rs
@@ -4052,6 +4052,7 @@ impl ProfileCreateBridge for api::ProfileCreate {
             is_pre_network_tokenization_enabled: self
                 .is_pre_network_tokenization_enabled
                 .unwrap_or_default(),
+            merchant_category_code: self.merchant_category_code,
         }))
     }
 
@@ -4200,6 +4201,7 @@ impl ProfileCreateBridge for api::ProfileCreate {
             external_vault_connector_details: self
                 .external_vault_connector_details
                 .map(ForeignInto::foreign_into),
+            merchant_category_code: self.merchant_category_code,
         }))
     }
 }
@@ -4533,6 +4535,7 @@ impl ProfileUpdateBridge for api::ProfileUpdate {
                 merchant_business_country: self.merchant_business_country,
                 is_iframe_redirection_enabled: self.is_iframe_redirection_enabled,
                 is_pre_network_tokenization_enabled: self.is_pre_network_tokenization_enabled,
+                merchant_category_code: self.merchant_category_code,
             },
         )))
     }
@@ -4672,6 +4675,7 @@ impl ProfileUpdateBridge for api::ProfileUpdate {
                 external_vault_connector_details: self
                     .external_vault_connector_details
                     .map(ForeignInto::foreign_into),
+                merchant_category_code: self.merchant_category_code,
             },
         )))
     }
diff --git a/crates/router/src/core/debit_routing.rs b/crates/router/src/core/debit_routing.rs
index adbd663c5c1..26505171fc3 100644
--- a/crates/router/src/core/debit_routing.rs
+++ b/crates/router/src/core/debit_routing.rs
@@ -315,7 +315,7 @@ pub async fn get_debit_routing_output<
             }
 
             let co_badged_card_request = open_router::CoBadgedCardRequest {
-                merchant_category_code: enums::MerchantCategoryCode::Mcc0001,
+                merchant_category_code: enums::DecisionEngineMerchantCategoryCode::Mcc0001,
                 acquirer_country,
                 co_badged_card_data,
             };
diff --git a/crates/router/src/types/api/admin.rs b/crates/router/src/types/api/admin.rs
index 41069a784b8..ac46c1dde00 100644
--- a/crates/router/src/types/api/admin.rs
+++ b/crates/router/src/types/api/admin.rs
@@ -199,6 +199,7 @@ impl ForeignTryFrom<domain::Profile> for ProfileResponse {
             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,
+            merchant_category_code: item.merchant_category_code,
         })
     }
 }
@@ -283,6 +284,7 @@ impl ForeignTryFrom<domain::Profile> for ProfileResponse {
             external_vault_connector_details: item
                 .external_vault_connector_details
                 .map(ForeignInto::foreign_into),
+            merchant_category_code: item.merchant_category_code,
         })
     }
 }
@@ -450,5 +452,6 @@ pub async fn create_profile_from_merchant_account(
         is_pre_network_tokenization_enabled: request
             .is_pre_network_tokenization_enabled
             .unwrap_or_default(),
+        merchant_category_code: request.merchant_category_code,
     }))
 }
diff --git a/migrations/2025-06-09-080126_add_merchant_category_code_in_business_profile/down.sql b/migrations/2025-06-09-080126_add_merchant_category_code_in_business_profile/down.sql
new file mode 100644
index 00000000000..532bb667ff2
--- /dev/null
+++ b/migrations/2025-06-09-080126_add_merchant_category_code_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 merchant_category_code;
\ No newline at end of file
diff --git a/migrations/2025-06-09-080126_add_merchant_category_code_in_business_profile/up.sql b/migrations/2025-06-09-080126_add_merchant_category_code_in_business_profile/up.sql
new file mode 100644
index 00000000000..125634a30e1
--- /dev/null
+++ b/migrations/2025-06-09-080126_add_merchant_category_code_in_business_profile/up.sql
@@ -0,0 +1,3 @@
+-- Your SQL goes here
+ALTER TABLE business_profile
+ADD COLUMN merchant_category_code VARCHAR(16) DEFAULT NULL;
\ No newline at end of file

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

- [ ] Bugfix
- [x] New feature
- [ ] Enhancement
- [ ] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD

## Description
<!-- Describe your changes in detail -->
This pull request introduces `merchant_category_code` field in the business profile. This is the four-digit code assigned based on business type to determine processing fees and risk level. This code can be used to make various decision during a payment flow. One such use case is network interchange fee calculation in debit routing.

* **Enum Enhancements**: Introduced two new enums, `MerchantCategory` and `MerchantCategoryCode`, to represent MCCs and their corresponding human-readable names. Implemented a mapping function `to_merchant_category_name` to convert MCCs to their names.

### WASM Functionality

* **Frontend Integration**: Added a new WASM function `getMerchantCategoryCodeWithName` to retrieve all MCCs along with their names for frontend use. This function iterates over the `MerchantCategoryCode` enum and constructs a list of MCCs and their human-readable names.

### Code Refactoring

* **Enum Renaming**: Renamed `MerchantCategoryCode` to `DecisionEngineMerchantCategoryCode` in specific contexts to clarify usage in decision engine logic. This is struct will be removed once the new struct is introduced in decision engine. 

-> Supported Merchant Category Codes
1. 5411
2. 7011
3. 0763
4. 8111
5. 5021
6. 4816
7. 5661

### Additional Changes

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

<!--
Provide links to the files with corresponding changes.

Following are the paths where you can find config files:
1. `config`
2. `crates/router/src/configs`
3. `loadtest/config`
-->


## 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).
-->


## 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)?
-->
-> Update a business profile by passing merchant category code
```
curl --location 'http://localhost:8080/account/merchant_1749476401/business_profile/pro_1RkvEPVmDc3K9FSyjOOS' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: ' \
--data '{
    "merchant_category_code": "5411"
}'
```
```
{
    "merchant_id": "merchant_1749476401",
    "profile_id": "pro_1RkvEPVmDc3K9FSyjOOS",
    "profile_name": "US_default",
    "return_url": "https://google.com/success",
    "enable_payment_response_hash": true,
    "payment_response_hash_key": "IfRVqwhR9vFVlA7sYWqPZvy6xNbM6wToe8N0WCEGykmFkTc7hYyycIbOCbGw3Hxo",
    "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": true,
    "merchant_business_country": null,
    "is_pre_network_tokenization_enabled": false,
    "merchant_category_code": "5411"
}
```
-> Db entry
![image](https://github.com/user-attachments/assets/1fd22d9e-ed8e-4ea1-9d9e-7d5a5f58afdf)

-> Wasm testing
<img width="737" alt="image" src="https://github.com/user-attachments/assets/e19488f1-f726-4522-b89d-6733a9f8504b" />


## 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**
  - Introduced support for merchant category codes across payment and profile APIs, enabling optional inclusion of standardized merchant category codes in payment intent requests and merchant profiles.
  - Added a public function to retrieve merchant category codes with their descriptive names via WebAssembly.
- **Database**
  - Added a new nullable column for merchant category codes to the business profile table.
- **API Documentation**
  - Updated API schemas and documentation to include merchant category code fields and enumerations.
- **Refactor**
  - Standardized and extended merchant category code enums for improved mapping and integration.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->