Skip to content

feat(router): add merchant_category_code in business profile#8296

Merged
SanchithHegde merged 12 commits intomainfrom
debit-routing/add-merchant-category-code-in-profile
Jun 12, 2025
Merged

feat(router): add merchant_category_code in business profile#8296
SanchithHegde merged 12 commits intomainfrom
debit-routing/add-merchant-category-code-in-profile

Conversation

@ShankarSinghC
Copy link
Contributor

@ShankarSinghC ShankarSinghC commented Jun 10, 2025

Type of Change

  • Bugfix
  • New feature
  • Enhancement
  • Refactoring
  • Dependency updates
  • Documentation
  • CI/CD

Description

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

  • This PR modifies the API contract
  • This PR modifies the database schema
  • This PR modifies application configuration/environment variables

Motivation and Context

How did you test it?

-> 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

-> Wasm testing
image

Checklist

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

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.

@ShankarSinghC ShankarSinghC self-assigned this Jun 10, 2025
@ShankarSinghC ShankarSinghC requested review from a team as code owners June 10, 2025 06:34
@ShankarSinghC ShankarSinghC added the A-framework Area: Framework label Jun 10, 2025
@ShankarSinghC ShankarSinghC requested a review from a team as a code owner June 10, 2025 06:34
@ShankarSinghC ShankarSinghC added A-core Area: Core flows M-database-changes Metadata: This PR involves database schema changes M-api-contract-changes Metadata: This PR involves API contract changes A-routing Area: Routing labels Jun 10, 2025
@semanticdiff-com
Copy link

semanticdiff-com bot commented Jun 10, 2025

@hyperswitch-bot hyperswitch-bot bot removed the M-api-contract-changes Metadata: This PR involves API contract changes label Jun 10, 2025
@ShankarSinghC ShankarSinghC linked an issue Jun 10, 2025 that may be closed by this pull request
@hyperswitch-bot hyperswitch-bot bot added the M-api-contract-changes Metadata: This PR involves API contract changes label Jun 10, 2025
@coderabbitai
Copy link

coderabbitai bot commented Jun 10, 2025

Walkthrough

Merchant category code support has been added throughout the API, data models, database schema, and OpenAPI specifications. This includes new enums for merchant category codes and names, new fields in profile-related structs, schema changes, migration scripts for the business profile table, type updates, and mapping logic. WASM support for retrieving codes with names was also introduced.

Changes

File(s) Change Summary
api-reference-v2/openapi_spec.json
api-reference/openapi_spec.json
Added MerchantCategoryCode enum schema and included it as an optional, nullable property in payment intent/request schemas.
crates/api_models/src/admin.rs
crates/hyperswitch_domain_models/src/business_profile.rs
Added optional merchant_category_code field to profile-related structs (create, update, response, setter, general update) for v1 and v2 APIs; updated conversions to include the field.
crates/diesel_models/src/business_profile.rs Added optional merchant_category_code field to business profile structs (Profile, ProfileNew, ProfileUpdateInternal) for v1 and v2; updated apply_changeset to handle the new field.
crates/diesel_models/src/schema.rs
crates/diesel_models/src/schema_v2.rs
Added nullable merchant_category_code column (VARCHAR(16)) to business_profile table schema.
migrations/2025-06-09-080126_add_merchant_category_code_in_business_profile/up.sql
down.sql
Migration scripts to add and remove merchant_category_code column in business_profile table.
crates/common_enums/src/enums.rs Renamed MerchantCategoryCode to DecisionEngineMerchantCategoryCode; introduced new MerchantCategoryCode and MerchantCategory enums, mapping logic, and a struct combining code and name.
crates/api_models/src/open_router.rs
crates/router/src/core/debit_routing.rs
Updated merchant_category_code field type in CoBadgedCardRequest and debit routing logic to use DecisionEngineMerchantCategoryCode.
crates/euclid_wasm/src/lib.rs Added WASM-exposed function to get all merchant category codes with their names.
crates/openapi/src/openapi.rs
crates/openapi/src/openapi_v2.rs
Included MerchantCategoryCode in OpenAPI schema components.
crates/router/src/core/admin.rs
crates/router/src/types/api/admin.rs
Added support for merchant_category_code in profile creation, update, and response flows.

Sequence Diagram(s)

sequenceDiagram
    participant API_Client
    participant Router
    participant Domain
    participant DieselModels
    participant Database

    API_Client->>Router: Create/Update Profile (merchant_category_code)
    Router->>Domain: Map API request to domain model (includes merchant_category_code)
    Domain->>DieselModels: Convert domain model to DB model (merchant_category_code)
    DieselModels->>Database: Insert/Update business_profile (merchant_category_code)
    Database-->>DieselModels: Confirmation
    DieselModels-->>Domain: DB model with merchant_category_code
    Domain-->>Router: Domain model with merchant_category_code
    Router-->>API_Client: API response (merchant_category_code)
Loading

Poem

Oh merchant code, you now appear,
In profiles, schemas, far and near!
With enums mapped and names in tow,
Through database and docs you flow.
A code for every merchant kind—
In every model, now aligned!
🐇✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 038c4a6 and 9771df6.

📒 Files selected for processing (1)
  • crates/diesel_models/src/business_profile.rs (10 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • crates/diesel_models/src/business_profile.rs
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Check wasm build
  • GitHub Check: Validate generated OpenAPI spec file
  • GitHub Check: Verify consistency of migrations with schema.rs file
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (5)
migrations/2025-06-09-080126_add_merchant_category_code_in_business_profile/up.sql (1)

1-3: Consider column type and migration idempotency
Merchant category codes are fixed four-digit values; you could enforce that with CHAR(4) instead of VARCHAR(16). Also, adding IF NOT EXISTS to the ADD COLUMN makes the migration safe to re-run.

crates/router/src/types/api/admin.rs (1)

453-453: Persist merchant_category_code on profile creation
The request field is forwarded into the ProfileSetter. Consider adding a unit test for create_profile_from_merchant_account to assert that merchant_category_code is correctly persisted.

api-reference/openapi_spec.json (2)

25071-25078: Document merchant_category_code in PaymentsCreateRequest.
The new property is currently undocumented. Add a description and an example to clarify its purpose and format:

           "merchant_category_code": {
+            "description": "Optional Merchant Category Code (MCC) for this payment, as defined in the MCC enum.",
+            "example": "5411",
             "allOf": [
               { "$ref": "#/components/schemas/MerchantCategoryCode" }
             ],
             "nullable": true

25363-25370: Document merchant_category_code in PaymentsRetrieveRequest.
Apply the same documentation enhancements here to maintain consistency:

           "merchant_category_code": {
+            "description": "Optional Merchant Category Code (MCC) for this payment, as defined in the MCC enum.",
+            "example": "7011",
             "allOf": [
               { "$ref": "#/components/schemas/MerchantCategoryCode" }
             ],
             "nullable": true
crates/hyperswitch_domain_models/src/business_profile.rs (1)

1036-1036: Remove unused import of serde::de::value
This import is not used within the function body and should be cleaned up.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b452442 and cd22a61.

📒 Files selected for processing (17)
  • api-reference-v2/openapi_spec.json (3 hunks)
  • api-reference/openapi_spec.json (3 hunks)
  • crates/api_models/src/admin.rs (6 hunks)
  • crates/api_models/src/open_router.rs (1 hunks)
  • crates/common_enums/src/enums.rs (2 hunks)
  • crates/diesel_models/src/business_profile.rs (10 hunks)
  • crates/diesel_models/src/schema.rs (1 hunks)
  • crates/diesel_models/src/schema_v2.rs (1 hunks)
  • crates/euclid_wasm/src/lib.rs (2 hunks)
  • crates/hyperswitch_domain_models/src/business_profile.rs (33 hunks)
  • crates/openapi/src/openapi.rs (1 hunks)
  • crates/openapi/src/openapi_v2.rs (1 hunks)
  • crates/router/src/core/admin.rs (4 hunks)
  • crates/router/src/core/debit_routing.rs (1 hunks)
  • crates/router/src/types/api/admin.rs (3 hunks)
  • migrations/2025-06-09-080126_add_merchant_category_code_in_business_profile/down.sql (1 hunks)
  • migrations/2025-06-09-080126_add_merchant_category_code_in_business_profile/up.sql (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
crates/openapi/src/openapi_v2.rs (1)
crates/euclid_wasm/src/lib.rs (1)
  • MerchantCategoryCode (98-103)
crates/openapi/src/openapi.rs (1)
crates/euclid_wasm/src/lib.rs (1)
  • MerchantCategoryCode (98-103)
🪛 GitHub Actions: Migration Consistency Tests
crates/diesel_models/src/schema_v2.rs

[error] 1-1: Migration command would result in changes to this file. Rerun the command locally and commit the changes.

⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: Check compilation for V2 features
  • GitHub Check: Run tests on stable toolchain (ubuntu-latest)
  • GitHub Check: Check compilation on MSRV toolchain (ubuntu-latest)
  • GitHub Check: Run Cypress tests
  • GitHub Check: Check wasm build
  • GitHub Check: Validate generated OpenAPI spec file
🔇 Additional comments (56)
crates/openapi/src/openapi_v2.rs (1)

288-288: Integration of MerchantCategoryCode schema looks good
The new api_models::enums::MerchantCategoryCode is correctly included in the OpenAPI components, ensuring it's exposed in the generated API documentation.

migrations/2025-06-09-080126_add_merchant_category_code_in_business_profile/down.sql (1)

1-2: Down migration aligns with the up migration
Dropping merchant_category_code with IF EXISTS cleanly reverses the addition, preventing errors if the column is already absent.

crates/diesel_models/src/schema.rs (1)

231-232: LGTM! Schema change is well-designed.

The addition of the nullable merchant_category_code field with a 16-character limit is appropriate. The VARCHAR(16) provides ample space for the 4-digit merchant category codes mentioned in the PR objectives while allowing for future flexibility, and the nullable constraint ensures backward compatibility.

crates/api_models/src/open_router.rs (1)

110-110: LGTM! Type change improves clarity.

The change from MerchantCategoryCode to DecisionEngineMerchantCategoryCode aligns with the PR objectives to clarify usage in decision engine contexts. This naming is more specific and appropriate for the CoBadgedCardRequest struct used in debit routing decisions.

crates/openapi/src/openapi.rs (1)

322-322: LGTM! Essential addition for API documentation.

Adding MerchantCategoryCode to the OpenAPI components schemas is necessary to properly document the new merchant category code functionality in the API specification. This enables proper schema generation and API client support for the MCC field.

crates/euclid_wasm/src/lib.rs (2)

37-37: LGTM!

The import update correctly includes the new merchant category code types needed for the new function.


94-108: LGTM!

The implementation follows the established pattern used by get_two_letter_country_code() and correctly exposes merchant category codes with their human-readable names to the frontend via WASM. The function properly handles iteration over the enum variants, mapping, and serialization.

crates/router/src/core/admin.rs (4)

4056-4056: LGTM! Consistent field assignment for merchant category code.

The field assignment follows the established pattern for optional fields and properly propagates the merchant_category_code from the API request to the domain model.


4205-4205: LGTM! Consistent v2 implementation.

The field assignment maintains consistency with the v1 implementation and properly handles the merchant_category_code in the v2 API flow.


4539-4539: LGTM! Completes v1 profile update support.

The field assignment properly handles merchant_category_code in profile update operations, maintaining consistency with the create operation.


4679-4679: LGTM! Completes comprehensive merchant category code support.

This final change ensures that merchant_category_code is consistently handled across all profile operations (create/update) and API versions (v1/v2). The implementation is complete and well-structured.

api-reference-v2/openapi_spec.json (3)

12989-13000: Define MerchantCategoryCode enum in components
The new enum correctly enumerates all supported MCC values as strings.


20744-20752: Expose merchant_category_code in Create Intent request
The property is properly marked nullable and references the new MerchantCategoryCode component.


21020-21028: Expose merchant_category_code in Update Intent request
The update schema correctly adds the nullable merchant_category_code field to the request body.

crates/router/src/types/api/admin.rs (2)

200-200: Map merchant_category_code in v1 ProfileResponse
The new field is correctly pulled from the domain model. Please verify that the ProfileResponse struct for v1 and its OpenAPI spec have been updated to include merchant_category_code.


285-285: Map merchant_category_code in v2 ProfileResponse
This aligns with the v1 change. Confirm that the v2 ProfileResponse struct and the OpenAPI V2 schema expose merchant_category_code as expected.

crates/diesel_models/src/business_profile.rs (10)

133-133: Insertable struct updated correctly
The ProfileNew struct now includes merchant_category_code, ensuring insert operations can set this field.


188-188: Include field in v1 changeset struct
The ProfileUpdateInternal struct’s AsChangeset now covers merchant_category_code, enabling updates to this column.


240-240: Destructure new field in v1 apply_changeset
The merchant_category_code variable is correctly included in the destructuring of self, so upstream updates carry into the merge logic.


323-323: Merge new field in v1 apply_changeset
The merge logic merchant_category_code: merchant_category_code.or(source.merchant_category_code) properly falls back to the existing value when no update is provided.


471-471: Insertable v2 struct updated correctly
The v2 ProfileNew struct now exposes merchant_category_code for insert operations.


529-529: Include field in v2 changeset struct
The v2 ProfileUpdateInternal struct’s AsChangeset derive now covers merchant_category_code, enabling PATCH updates on this field.


584-584: Destructure new field in v2 apply_changeset
The destructuring of self in the v2 merge now includes merchant_category_code, so the update payload captures this change.


677-677: Merge new field in v2 apply_changeset
The merge logic merchant_category_code: merchant_category_code.or(source.merchant_category_code) correctly handles fallback when the update does not specify a new code.


397-397:

Details

✅ Verification successful

Ensure v2 schema alignment for new field
Added merchant_category_code to the v2 Profile struct. Verify the v2 schema (schema_v2.rs) includes this column at the matching position to prevent Diesel compile errors.


🏁 Script executed:

#!/bin/bash
# Verify merchant_category_code exists in v2 schema_v2.rs
rg "merchant_category_code" -n crates/diesel_models/src/schema_v2.rs

Length of output: 125


v2 schema includes merchant_category_code

  • Verified in crates/diesel_models/src/schema_v2.rs (line 242):
    merchant_category_code -> Nullable<Varchar>,

No further action required.


77-77:

Details

✅ Verification successful

Ensure v1 schema alignment for new field
Added merchant_category_code to the v1 Profile struct. Verify that the business_profile table schema (schema.rs) has the nullable merchant_category_code column in the correct position to match this struct field order.


🏁 Script executed:

#!/bin/bash
# Verify merchant_category_code exists in v1 schema.rs
rg "merchant_category_code" -n crates/diesel_models/src/schema.rs

Length of output: 122


🏁 Script executed:

#!/bin/bash
# Show struct context for merchant_category_code field
rg -n -C5 "merchant_category_code" crates/diesel_models/src/business_profile.rs

# Show schema context for merchant_category_code column
rg -n -C5 "merchant_category_code" crates/diesel_models/src/schema.rs

Length of output: 6152


v1 schema alignment confirmed

  • In crates/diesel_models/src/business_profile.rs, the merchant_category_code field appears immediately after three_ds_decision_rule_algorithm in the Profile struct (around line 77).
  • In crates/diesel_models/src/schema.rs, merchant_category_code -> Nullable<Varchar> is declared right after three_ds_decision_rule_algorithm within the business_profile table (line 232).

The column ordering matches the struct. Ready to merge.

crates/api_models/src/admin.rs (6)

2022-2024: Add merchant_category_code to ProfileCreate (v1)
The new optional field aligns with other business profile properties, and the schema metadata correctly reflects a four-digit MCC.


2167-2169: Add merchant_category_code to ProfileCreate (v2)
This mirrors the v1 addition and ensures the MCC is exposed in the v2 create payload with proper schema documentation.


2334-2336: Add merchant_category_code to ProfileResponse (v1)
Including the MCC in the v1 response completes the contract for clients reading business profiles.


2487-2489: Add merchant_category_code to ProfileResponse (v2)
The v2 response now consistently surfaces the merchant’s category code alongside other profile details.


2647-2649: Add merchant_category_code to ProfileUpdate (v1)
Allowing updates to the MCC in v1 aligns with the create and response models for full CRUD support.


2783-2785: Add merchant_category_code to ProfileUpdate (v2)
This completes the v2 update contract by permitting MCC modifications with correct schema metadata.

crates/common_enums/src/enums.rs (5)

2400-2403: LGTM! Clean enum rename with appropriate attributes.

The DecisionEngineMerchantCategoryCode enum is well-defined with proper serialization and diesel integration. The rename from MerchantCategoryCode to clarify its specific usage in decision engine logic is a good architectural decision.


2503-2535: Excellent design for human-readable merchant category names.

The MerchantCategory enum provides clear, descriptive names with proper serde renaming to include the MCC codes in parentheses. This approach enhances readability while maintaining the connection to the underlying codes.


2537-2575: Well-structured merchant category code enum with proper string serialization.

The enum correctly represents all seven supported MCCs (5411, 7011, 0763, 8111, 5021, 4816, 5661) with consistent naming and appropriate diesel integration for database storage as text.


2577-2589: Perfect mapping implementation between codes and names.

The to_merchant_category_name method provides a clean, exhaustive mapping from each MCC code to its corresponding human-readable category. The implementation correctly covers all enum variants and follows Rust best practices.


2591-2595: Clean and practical struct design for combining code and name.

The MerchantCategoryCodeWithName struct provides a simple, effective way to package merchant category codes with their descriptive names for API responses and frontend consumption.

crates/hyperswitch_domain_models/src/business_profile.rs (19)

79-79: Add merchant_category_code to v1 Profile struct
Introduces the new optional MCC field to the core v1 domain model.


133-133: Add merchant_category_code to v1 ProfileSetter struct
Ensures the setter supports the new MCC field during profile creation/update.


193-194: Map merchant_category_code in v1 From<ProfileSetter> conversion
Propagates the setter’s MCC into the concrete Profile.


254-254: Add merchant_category_code to v1 ProfileGeneralUpdate struct
Allows MCC to be updated via the general update payload.


331-331: Destructure merchant_category_code in v1 ProfileUpdate::Update
Pulls the MCC out of the update wrapper for conversion.


382-382: Set merchant_category_code in v1 ProfileUpdateInternal::Update
Includes the new MCC field in the internal changeset.


434-434: Default MCC to None in v1 non-general update variants
Ensures that update variants unrelated to general profile changes do not overwrite MCC.

Also applies to: 484-484, 534-534, 584-584, 634-634, 684-684


754-754: Include merchant_category_code in v1 Conversion::convert
Writes the domain MCC into the Diesel Profile for persistence.


850-850: Include merchant_category_code in v1 Conversion::convert_back
Restores the MCC from the database model back into the domain struct.


914-914: Include merchant_category_code in v1 Conversion::construct_new
Ensures new database inserts carry the MCC field.


974-974: Add merchant_category_code to v2 Profile struct
Adds the optional MCC to the v2 domain model for profiles.


1030-1030: Add merchant_category_code to v2 ProfileSetter struct
Supports the MCC field during v2 profile creation and updates.


1093-1093: Map merchant_category_code in v2 From<ProfileSetter> conversion
Transfers the MCC from the setter into the v2 Profile.


1173-1173: Add merchant_category_code to v2 ProfileGeneralUpdate struct
Enables MCC updates in the v2 general update payload.


1252-1252: Handle merchant_category_code in v2 ProfileUpdate::Update
Destructures and sets the MCC in the internal update conversion.

Also applies to: 1304-1304


1359-1359: Default MCC to None in v2 non-general update variants
Prevents unrelated update variants from clearing or altering the MCC.

Also applies to: 1412-1412, 1465-1465, 1518-1518, 1571-1571, 1624-1624, 1678-1678, 1730-1730, 1784-1784


1860-1860: Include merchant_category_code in v2 Conversion::convert
Persists the MCC into the Diesel Profile on conversion.


1954-1954: Include merchant_category_code in v2 Conversion::convert_back
Restores the MCC from the DB model into the v2 domain struct.


2023-2023: Include merchant_category_code in v2 Conversion::construct_new
Ensures new v2 inserts include the MCC field.

Comment on lines +241 to +242
#[max_length = 16]
merchant_category_code -> Nullable<Varchar>,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Schema out-of-sync: rerun Diesel CLI to update schema_v2.rs
CI migration consistency tests are failing. Please rerun the Diesel schema generation to reflect the new column, for example:

diesel print-schema --schema v2 > crates/diesel_models/src/schema_v2.rs
🤖 Prompt for AI Agents
In crates/diesel_models/src/schema_v2.rs around lines 241 to 242, the schema is
out-of-sync with the database, causing CI migration consistency tests to fail.
To fix this, rerun the Diesel CLI command `diesel print-schema --schema v2 >
crates/diesel_models/src/schema_v2.rs` to regenerate the schema file and update
it with the latest database changes.


let co_badged_card_request = open_router::CoBadgedCardRequest {
merchant_category_code: enums::MerchantCategoryCode::Mcc0001,
merchant_category_code: enums::DecisionEngineMerchantCategoryCode::Mcc0001,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Use the actual merchant category code from business profile instead of hardcoded value.

The hardcoded Mcc0001 value should be replaced with the actual merchant_category_code from the business profile. According to the PR objectives, the business profile now contains this field, but it's not being utilized here.

Apply this diff to use the business profile's merchant category code:

-                merchant_category_code: enums::DecisionEngineMerchantCategoryCode::Mcc0001,
+                merchant_category_code: business_profile.merchant_category_code
+                    .unwrap_or(enums::DecisionEngineMerchantCategoryCode::Mcc0001),

Note: You may need to adjust the enum conversion depending on the exact type stored in the business profile.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
merchant_category_code: enums::DecisionEngineMerchantCategoryCode::Mcc0001,
merchant_category_code: business_profile.merchant_category_code
.unwrap_or(enums::DecisionEngineMerchantCategoryCode::Mcc0001),
🤖 Prompt for AI Agents
In crates/router/src/core/debit_routing.rs at line 318, replace the hardcoded
merchant_category_code value enums::DecisionEngineMerchantCategoryCode::Mcc0001
with the actual merchant_category_code obtained from the business profile.
Retrieve the merchant_category_code field from the business profile object and
convert or map it appropriately to the enums::DecisionEngineMerchantCategoryCode
type before assigning it here.

Comment on lines +15574 to +15585
"MerchantCategoryCode": {
"type": "string",
"enum": [
"5411",
"7011",
"0763",
"8111",
"5021",
"4816",
"5661"
]
},
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add description, pattern, and example to MerchantCategoryCode schema.
The new enum schema lacks a description, pattern constraint, and an example. Including these enhances clarity, enforces the 4-digit format, and aids API consumers.
Suggestion:

   "MerchantCategoryCode": {
-    "type": "string",
-    "enum": [
+    "type": "string",
+    "description": "Merchant Category Code (MCC), a 4-digit ISO-assigned code for merchant classification.",
+    "pattern": "^[0-9]{4}$",
+    "enum": [
       "5411",
       "7011",
       "0763",
       "8111",
       "5021",
       "4816",
       "5661"
     ],
+    "example": "5411"
   },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"MerchantCategoryCode": {
"type": "string",
"enum": [
"5411",
"7011",
"0763",
"8111",
"5021",
"4816",
"5661"
]
},
"MerchantCategoryCode": {
"type": "string",
"description": "Merchant Category Code (MCC), a 4-digit ISO-assigned code for merchant classification.",
"pattern": "^[0-9]{4}$",
"enum": [
"5411",
"7011",
"0763",
"8111",
"5021",
"4816",
"5661"
],
"example": "5411"
},
🤖 Prompt for AI Agents
In api-reference/openapi_spec.json around lines 15574 to 15585, the
MerchantCategoryCode schema is missing a description, a pattern to enforce the
4-digit format, and an example value. Add a "description" field explaining that
this is a 4-digit merchant category code, include a "pattern" field with a regex
to enforce exactly four digits, and add an "example" field with a valid code
such as "5411" to improve schema clarity and validation.

Chethan-rao
Chethan-rao previously approved these changes Jun 11, 2025
@likhinbopanna likhinbopanna added this pull request to the merge queue Jun 11, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to a conflict with the base branch Jun 11, 2025
…it-routing/add-merchant-category-code-in-profile
@likhinbopanna likhinbopanna enabled auto-merge June 12, 2025 08:02
@SanchithHegde SanchithHegde disabled auto-merge June 12, 2025 10:05
@SanchithHegde SanchithHegde added this pull request to the merge queue Jun 12, 2025
Merged via the queue into main with commit 0f14279 Jun 12, 2025
15 of 20 checks passed
@SanchithHegde SanchithHegde deleted the debit-routing/add-merchant-category-code-in-profile branch June 12, 2025 11:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-core Area: Core flows A-framework Area: Framework A-routing Area: Routing M-api-contract-changes Metadata: This PR involves API contract changes M-database-changes Metadata: This PR involves database schema changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

add merchant_category_code in business profile

4 participants