Shared Catalogs in Magento 2: Customer-Specific Catalogs and Pricing Strategy
AI generated
M2
di.xml
Magento 2 · B2B Suite
Shared Catalogs
Customer-specific catalogs and pricing strategy explained

Shared Catalogs control, for every company, which categories are visible and at what prices products can be ordered, built on the same Category Permissions that also exist outside the B2B Suite. Understanding the mechanics behind it lets teams control visibility and price overrides deliberately, instead of getting surprised by indexing problems once the catalog count grows.

12 min read Shared Catalogs · B2B Suite Magento 2.4.x Commerce

1. Placing Shared Catalogs in a B2B context

A Shared Catalog is a named subset of the public catalog that gets assigned to one or more companies, controlling which categories and products are even visible to their members. Unlike a plain customer group price rule, a Shared Catalog therefore goes beyond pricing and additionally affects the visibility of entire categories.

In the default setup, every company is assigned to exactly one Shared Catalog, the public catalog by default, which shows every category without restriction. Once a custom Shared Catalog is created and assigned to a company, its members see only the categories released within it, regardless of what the catalog looks like for anonymous visitors or other companies.

2. Technical setup: a hidden customer group and Category Permissions

Under the hood, a Shared Catalog is not an entirely new concept but a combination of two existing mechanisms. When a Shared Catalog is created, Magento automatically generates its own customer group, hidden from administrators in the regular customer group grid, that serves internally as the link between company and catalog. That hidden group is then used exactly like a regular customer group by the category permissions functionality of the Magento_CatalogPermissions module.

For every category, a permission of ALLOW, DENY or ALLOW_PARTIAL can be stored per customer group, where ALLOW_PARTIAL shows the category in navigation but blocks the product content. A Shared Catalog sets these permissions deliberately for its hidden customer group, so categories outside the released structure remain effectively invisible for members of the assigned company, while technically still being filtered through the category permissions index.


<?php

declare(strict_types=1);

namespace Mironsoft\SharedCatalogExtension\Model;

use Magento\CatalogPermissions\App\ConfigInterface;
use Magento\CatalogPermissions\Model\Permission;
use Magento\SharedCatalog\Api\SharedCatalogRepositoryInterface;

/**
 * Reads the effective category permission for a shared catalog's hidden
 * customer group, used to evaluate it in a custom report.
 */
class SharedCatalogPermissionReader
{
    /**
     * @param SharedCatalogRepositoryInterface $sharedCatalogRepository
     * @param ConfigInterface $permissionsConfig
     */
    public function __construct(
        private readonly SharedCatalogRepositoryInterface $sharedCatalogRepository,
        private readonly ConfigInterface $permissionsConfig,
    ) {
    }

    /**
     * Returns true if the given category is visible for the shared catalog.
     *
     * @param int $sharedCatalogId
     * @param int $categoryId
     * @return bool
     */
    public function isCategoryVisible(int $sharedCatalogId, int $categoryId): bool
    {
        $sharedCatalog = $this->sharedCatalogRepository->get($sharedCatalogId);
        $customerGroupId = (int) $sharedCatalog->getCustomerGroupId();

        return $this->permissionsConfig->getPermission($categoryId, 0, $customerGroupId)
            !== Permission::PERMISSION_DENY;
    }
}

3. Keeping visibility and purchasability separate

A common misunderstanding is treating visibility and purchasability as the same mechanism. Category Permissions control exclusively whether a category or product shows up in navigation and search, not whether a product can actually be ordered. A product can be technically visible yet still not orderable through other mechanisms such as stock or minimum order quantities, and conversely a product can be made invisible through a DENY rule even though it would be orderable in terms of price and stock.

For custom extensions this means visibility checks and price checks have to be implemented separately. Anyone building a custom product feed for a Shared Catalog cannot rely solely on the category permissions index, but must also factor in the catalog's price overrides and the product's regular catalog visibility to get a consistent result.

4. Price overrides per catalog

Besides visibility, the second core function of a Shared Catalog is pricing. For every catalog, each product can have either a fixed price or a percentage or absolute deviation from the regular catalog price stored against it. Technically these overrides run through the same price rule infrastructure used for regular catalog price rules, just targeted at the hidden customer group of the given shared catalog.

For maintaining large price lists, the admin offers an export as an Excel sheet where price and visibility can be edited together per product and then re-imported. For automated price maintenance from an external ERP system, a custom import against the price rule APIs is preferable instead, using the same data path but without the manual Excel detour, and integrating into an existing price synchronization process.

5. Managing Shared Catalogs programmatically

Through Magento\SharedCatalog\Api\SharedCatalogRepositoryInterface and SharedCatalogManagementInterface, shared catalogs can be fully created, assigned categories, and linked to companies programmatically, without touching the admin manually. That matters particularly for projects where new company customers get created automatically from an external system and need a matching catalog assigned right away.

For bulk operations, such as adjusting hundreds of product prices in a catalog at once, calling the price rule services directly is considerably more efficient than hundreds of individual repository calls, because it avoids unnecessary individual transactions and repeated recalculation of the price rule.

6. Automatic catalog assignment via plugin

A typical extension case is automatically assigning a matching Shared Catalog as soon as a new company is created, for example based on a custom attribute such as customer segment or sales region. A plugin on company creation is the right fit here, checking after a successful save which shared catalog matches the stored rule and performing the assignment automatically.

It matters not to run the assignment inside the before part of a plugin, because the company ID is not yet known at that point. An after plugin on the save method is the correct approach here, since the fully saved company entity, including its ID, is available and the assignment can be performed reliably.


<?php

declare(strict_types=1);

namespace Mironsoft\SharedCatalogExtension\Plugin;

use Magento\Company\Api\CompanyRepositoryInterface;
use Magento\Company\Api\Data\CompanyInterface;
use Magento\SharedCatalog\Api\SharedCatalogManagementInterface;
use Mironsoft\SharedCatalogExtension\Model\SegmentCatalogResolver;

/**
 * Automatically assigns the shared catalog matching the customer segment
 * to a newly created company.
 */
class AssignCatalogOnCompanyCreatePlugin
{
    /**
     * @param SegmentCatalogResolver $catalogResolver
     * @param SharedCatalogManagementInterface $catalogManagement
     */
    public function __construct(
        private readonly SegmentCatalogResolver $catalogResolver,
        private readonly SharedCatalogManagementInterface $catalogManagement,
    ) {
    }

    /**
     * @param CompanyRepositoryInterface $subject
     * @param CompanyInterface $result
     * @return CompanyInterface
     */
    public function afterSave(CompanyRepositoryInterface $subject, CompanyInterface $result): CompanyInterface
    {
        $sharedCatalogId = $this->catalogResolver->resolveForCompany($result);
        if ($sharedCatalogId !== null) {
            $this->catalogManagement->assignCompany((int) $result->getId(), $sharedCatalogId);
        }

        return $result;
    }
}

7. Indexing: category permissions and the price index

Every shared catalog internally creates its own customer group, and both the category permissions index and the product price index operate over a matrix of customer group by category, or customer group by product respectively. With every additional shared catalog that matrix grows, which directly affects the runtime of the corresponding indexers, especially on large catalogs with many categories.

In practice this means a full reindex after creating several new shared catalogs can take noticeably longer than before, because both visibility and price calculations have to run again for each additional hidden group. Anyone planning many parallel catalogs should keep the indexer mode and the available resources of the indexing cron in mind accordingly.

8. Performance implications with many shared catalogs

Past a certain number of parallel shared catalogs, in practice often somewhere in the mid double digits depending on catalog and category size, the indexing load becomes noticeable. Instead of creating a separate catalog for every single customer segment, consolidation often pays off: similar pricing strategies can frequently be covered through shared catalogs with additional, more granular price rules, instead of creating a new hidden customer group for every small deviation.

For stores with genuinely many different company customers, it is also worth deliberately scheduling the full reindex outside peak hours and using the schedule mode for the affected indexers, instead of triggering an immediate, synchronous recalculation across the entire catalog on every small price change.

9. Operations: maintenance and traceability

Since shared catalogs control both visibility and pricing, clear internal documentation of which catalog maps to which customer segment with which pricing logic pays off. Without that overview, it quickly becomes unclear as the catalog count grows which company sees which prices, especially when several catalogs have been maintained by different team members over time.

For audits and support requests, it is also worth being able to trace the underlying customer group assignment and the category permissions entries directly in the database, not just through the admin interface, particularly when a customer reports seeing, or not seeing, a product incorrectly.

Aspect Public catalog Shared Catalog Technical basis
Visibility All categories visible Only released categories Category permissions per customer group
Pricing Regular catalog prices Fixed or deviating prices Price rules on hidden customer group
Customer group Standard groups Automatically created hidden group Generated when catalog is created
Assignment No assignment needed Exactly one catalog per company SharedCatalogManagementInterface
Index load Constant Grows with each catalog Customer group by category matrix
Maintenance Central in the catalog Excel export/import per catalog SharedCatalog admin grid

Mironsoft

Magento development, module consulting, and system architecture

A Magento project that needs a second opinion or experienced execution?

We build custom Magento modules, advise on architecture decisions, and take on complex implementations, from service contract planning to production-ready deployment.

Architecture Consulting

Have module and system architecture thought through properly before you build.

Custom Module Development

Build custom Magento modules cleanly, following best practices.

Code Review & Audit

Have existing modules reviewed for performance, security, and maintainability.

10. Summary

Shared Catalogs Pricing Strategy

Technical basis

Every shared catalog creates a hidden customer group, controlled through category permissions.

Pricing

Price overrides run through the same price rule infrastructure as regular catalog price rules.

Separation

Visibility and purchasability are separate mechanisms and must be checked separately in custom extensions.

Performance

Many parallel catalogs enlarge the indexing matrix, consolidation reduces the load noticeably.

11. FAQ: Shared Catalogs Pricing Strategy

1What is a Shared Catalog technically?
A named subset of the public catalog, internally linked to category permissions and price rules through an automatically created hidden customer group, and assigned to a company.
2Can a company be assigned to multiple shared catalogs?
No, in the default setup every company is assigned to exactly one shared catalog, the public catalog without restrictions by default.
3Do category permissions also control whether a product is orderable?
No, they exclusively control visibility in navigation and search. Purchasability additionally depends on stock, minimum quantities and other mechanisms.
4How are price overrides per catalog stored?
Through the same price rule infrastructure as regular catalog price rules, applied specifically to the hidden customer group of the given shared catalog.
5How can catalog assignment be automated?
Through an after plugin on company save logic that, after a successful save, determines the matching catalog based on an attribute and assigns it via SharedCatalogManagementInterface.
6Why does the indexing load grow with the number of shared catalogs?
Because both category permissions and the price index operate over a matrix of customer group by category or product, which grows with every additional hidden group.
7Is there a recommended maximum number of shared catalogs?
There is no fixed limit, but in the mid double digits the indexing load becomes noticeable in practice, which is why consolidating similar pricing strategies is worthwhile.
8How can large price lists for a catalog be maintained?
Through the Excel export and import in the admin grid for manual maintenance, or through a custom import against the price rule APIs for automated synchronization with an external system.
9Can shared catalogs be managed fully programmatically?
Yes, through SharedCatalogRepositoryInterface and SharedCatalogManagementInterface, catalogs can be created, assigned categories, and linked to companies without touching the admin manually.
10What should be considered when debugging visibility issues?
It is worth tracing the underlying customer group assignment and the category permissions entries directly in the database, not just the admin interface, to find the actual root cause.