Install the Merchant feature

Edit on GitHub

This document describes how to install the Merchant feature.

Prerequisites

Install the required features:

NAME VERSION INSTALLATION GUIDE
Spryker Core 202507.0 Install the Spryker Core feature

1) Install the required modules

Install the required modules using Composer:

composer require spryker-feature/merchant
Verification

Make sure the following modules have been installed:

MODULE EXPECTED DIRECTORY
Merchant spryker/merchant
MerchantDataImport spryker/merchant-data-import
MerchantGui spryker/merchant-gui
MerchantSearch spryker/merchant-search
MerchantSearchExtension vendor/spryker/merchant-search-extension
MerchantStorage spryker/merchant-storage

2) Set up the database schema and transfer objects

  1. Adjust the schema definition so entity changes trigger events:

src/Pyz/Zed/MerchantSearch/Persistence/Propel/Schema/spy_merchant_search.schema.xml

<?xml version="1.0"?>
  <database xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:noNamespaceSchemaLocation="http://static.spryker.com/schema-01.xsd" name="zed"
            namespace="Orm\Zed\MerchantSearch\Persistence"
            package="src.Orm.Zed.MerchantSearch.Persistence">

      <table name="spy_merchant_search">
          <behavior name="synchronization">
              <parameter name="queue_pool" value="synchronizationPool"/>
          </behavior>
      </table>

  </database>

  1. Apply database changes, generate entity and transfer changes:
console propel:install
console transfer:generate
Verification

Make sure the following changes have been applied in the database:

DATABASE SECURITY TYPE EVENT
spy_merchant table created
spy_merchant_store table created
spy_merchant_storage table created
spy_merchant_search table created
Verification

Make sure the following changes have occurred in transfer objects:

TRANSFER TYPE EVENT PATH
Merchant class Created src/Generated/Shared/Transfer/Merchant
MerchantCriteria class Created src/Generated/Shared/Transfer/MerchantCriteria
MerchantResponse class Created src/Generated/Shared/Transfer/MerchantResponse
MerchantCollection class Created src/Generated/Shared/Transfer/MerchantCollection
MerchantError class Created src/Generated/Shared/Transfer/MerchantError
MerchantSearch class Created src/Generated/Shared/Transfer/MerchantSearchTransfer
MerchantSearchCollection class Created src/Generated/Shared/Transfer/MerchantSearchCollection
MerchantSearchRequest class Created src/Generated/Shared/Transfer/MerchantSearchRequest
MerchantStorage class Created src/Generated/Shared/Transfer/MerchantStorage
MerchantStorageProfile class Created src/Generated/Shared/Transfer/MerchantStorageProfile
MerchantStorageProfileAddress class Created src/Generated/Shared/Transfer/MerchantStorageProfileAddress
MerchantStorageCriteria class Created src/Generated/Shared/Transfer/MerchantStorageCriteria
MerchantStorageProfile class Created src/Generated/Shared/Transfer/MerchantStorageProfile
DataImporterReaderConfiguration class created src/Generated/Shared/Transfer/DataImporterReaderConfigurationTransfer
SpyMerchantEntity class Created src/Generated/Shared/Transfer/SpyMerchantEntityTransfer
SpyMerchantStoreEntity class Created src/Generated/Shared/Transfer/SpyMerchantStoreEntityTransfer
SpyMerchantSearchEntity class Created src/Generated/Shared/Transfer/SpyMerchantSearchEntityTransfer
SpyMerchantStorageEntity class Created src/Generated/Shared/Transfer/SpyMerchantStorageEntityTransfer

3) Add Zed translations

Generate a new translation cache for Zed:

console translator:generate-cache

4) Import merchants data

  1. Prepare data according to your requirements using the demo data:

data/import/common/common/marketplace/merchant.csv

merchant_reference,merchant_name,registration_number,status,email,is_active,url.de_DE,url.en_US
MER000006,Sony Experts,HYY 134306,approved,michele@sony-experts.com,1,/de/merchant/sony-experts,/en/merchant/sony-experts
MER000005,Budget Cameras,HXX 134305,approved,jason.weidmann@budgetcamerasonline.com,1,/de/merchant/budget-cameras,/en/merchant/budget-cameras
MER000004,Impala Merchant,3,waiting-for-approval,impala.merchant@merchant.kudu,0,/en/merchant/impala-merchant-1,/de/merchant/impala-merchant-1
MER000003,Sugar Monster,4,waiting-for-approval,sugar.monster@merchant.kudu,0,/de/merchant/sugar-monster,/en/merchant/sugar-monster
MER000007,Restrictions Merchant,5,waiting-for-approval,restrictions.merchant@merchant.kudu,0,/de/merchant/restrictions-merchant,/en/merchant/restrictions-merchant
MER000001,Spryker,HRB 134310,approved,harald@spryker.com,1,/de/merchant/spryker,/en/merchant/spryker
MER000002,Video King,1234.4567,approved,martha@video-king.nl,1,/de/merchant/video-king,/en/merchant/video-king
COLUMN REQUIRED DATA TYPE DATA TYPE DATA EXPLANATION
merchant_reference string MER000006 Non-database identifier for a merchant.
merchant_name string Sony Experts Merchant profile page URL for the de_DE locale.
registration_number string HYY 134306 Official registration number as a legal entity of the merchant.
status string approved Status of the merchant in the system. A status pseudo state machine can be configured to allow for transitions, but this is the initial status for a merchant while importing.
email string [email protected] Email to contact the merchant.
is_active boolean 1 Defines if the merchant is active.
url optional(per locale) string /de/merchant/sony-experts Unique Storefront identifier for a merchant’s page.

data/import/common/common/marketplace/merchant_store.csv

>merchant_reference,store_name
MER000001,DE
MER000002,DE
MER000006,DE
MER000005,DE
MER000004,DE
MER000003,DE
MER000007,DE
COLUMN REQUIRED DATA TYPE DATA EXAMPLE DATA EXPLANATION
merchant_reference string MER000006 Merchant identifier.
store_name string DE Store name to which the merchant will be assigned.
  1. Register the following plugins to enable data import:
PLUGIN SPECIFICATION PREREQUISITES NAMESPACE
MerchantDataImportPlugin Imports merchant data into the database. Spryker\Zed\MerchantDataImport\Communication\Plugin\MerchantDataImportPlugin
MerchantStoreDataImportPlugin Imports merchant store assignments into the database. MerchantDataImportPlugin Spryker\Zed\MerchantDataImport\Communication\Plugin\MerchantStoreDataImportPlugin

src/Pyz/Zed/DataImport/DataImportDependencyProvider.php

<?php

namespace Pyz\Zed\DataImport;

use Spryker\Zed\DataImport\DataImportDependencyProvider as SprykerDataImportDependencyProvider;
use Spryker\Zed\MerchantDataImport\Communication\Plugin\MerchantDataImportPlugin;
use Spryker\Zed\MerchantDataImport\Communication\Plugin\MerchantStoreDataImportPlugin;

class DataImportDependencyProvider extends SprykerDataImportDependencyProvider
{
    protected function getDataImporterPlugins(): array
    {
        return [
            new MerchantDataImportPlugin(),
            new MerchantStoreDataImportPlugin(),
        ];
    }
}
  1. Import data:
console data:import merchant
console data:import merchant-store
Verification

Make sure that the data has been added to the spy_merchant and spy_merchant_store tables.

5) Set up behavior

Enable the following behaviors by registering the plugins:

PLUGIN DESCRIPTION PREREQUISITES NAMESPACE
StoreRelationToggleFormTypePlugin Adds the store relation toggle form to the MerchantGui Merchant creation and editing forms. Spryker\Zed\Store\Communication\Plugin\Form\StoreRelationToggleFormTypePlugin

current/src/Pyz/Zed/MerchantGui/MerchantGuiDependencyProvider.php

<?php

/**
 * This file is part of the Spryker Commerce OS.
 * For full license information,  view the LICENSE file that was distributed with this source code.
 */

namespace Pyz\Zed\MerchantGui;

use Spryker\Zed\Kernel\Communication\Form\FormTypeInterface;
use Spryker\Zed\MerchantGui\MerchantGuiDependencyProvider as SprykerMerchantGuiDependencyProvider;
use Spryker\Zed\Store\Communication\Plugin\Form\StoreRelationToggleFormTypePlugin;

class MerchantGuiDependencyProvider extends SprykerMerchantGuiDependencyProvider
{
    /**
     * @return \Spryker\Zed\Kernel\Communication\Form\FormTypeInterface
     */
    protected function getStoreRelationFormTypePlugin(): FormTypeInterface
    {
        return new StoreRelationToggleFormTypePlugin();
    }
}
Verification

Make sure that the merchant edit and create forms contain a Store toggle form.

7) Configure export to the key-value store (Redis or Valkey) and Elasticsearch

This step publishes tables on change (create, edit) to spy_merchant_profile_storage and synchronizes data to Storage.

Configure export to the key-value store (Redis or Valkey)

  1. Set up event listeners and publishers:
PLUGIN SPECIFICATION PREREQUISITES NAMESPACE
MerchantPublisherTriggerPlugin Registers the publishers that publish merchant entity changes to the storage. Spryker\Zed\MerchantStorage\Communication\Plugin\Publisher\MerchantPublisherTriggerPlugin
MerchantStoragePublisherPlugin Publishes merchant data to the spy_merchant_storage table. Spryker\Zed\MerchantStorage\Communication\Plugin\Publisher\Merchant\MerchantStoragePublisherPlugin
MerchantProductOfferStorageExpanderPlugin Returns the ProductOfferStorage transfer object expanded with Merchant. Spryker\Client\MerchantStorage\Plugin\ProductOfferStorage
MerchantProductOfferStorageFilterPlugin Filters the ProductOfferCollection transfer object by an active and approved merchant. Spryker\Zed\MerchantStorage\Communication\Plugin\ProductOfferStorage
UrlStorageMerchantMapperPlugin Provides access to merchant storage data in the controller related to the https://mysprykershop.com/merchant/{merchantReference} URL. Publish URL storage data to the key-value store (Redis or Valkey) by running console sync:data url. Spryker\Client\MerchantStorage\Plugin

src/Pyz/Zed/Publisher/PublisherDependencyProvider.php

<?php

namespace Pyz\Zed\Publisher;

use Spryker\Zed\Publisher\PublisherDependencyProvider as SprykerPublisherDependencyProvider;
use Spryker\Zed\MerchantStorage\Communication\Plugin\Publisher\MerchantPublisherTriggerPlugin;
use Spryker\Zed\MerchantStorage\Communication\Plugin\Publisher\Merchant\MerchantStoragePublisherPlugin;

class PublisherDependencyProvider extends SprykerPublisherDependencyProvider
{
   /**
     * @return array<\Spryker\Zed\PublisherExtension\Dependency\Plugin\PublisherPluginInterface>
     */
    protected function getPublisherPlugins(): array
    {
        return [
            new MerchantStoragePublisherPlugin(),
        ];
    }

    /**
     * @return array<\Spryker\Zed\PublisherExtension\Dependency\Plugin\PublisherTriggerPluginInterface>
     */
    protected function getPublisherTriggerPlugins(): array
    {
        return [
            new MerchantPublisherTriggerPlugin(),
        ];
    }
}

src/Pyz/Client/ProductOfferStorage/ProductOfferStorageDependencyProvider.php

<?php

namespace Pyz\Client\ProductOfferStorage;

use Spryker\Client\MerchantStorage\Plugin\ProductOfferStorage\MerchantProductOfferStorageExpanderPlugin;
use Spryker\Client\ProductOfferStorage\ProductOfferStorageDependencyProvider as SprykerProductOfferStorageDependencyProvider;

class ProductOfferStorageDependencyProvider extends SprykerProductOfferStorageDependencyProvider
{
    /**
     * @return array<\Spryker\Client\ProductOfferStorageExtension\Dependency\Plugin\ProductOfferStorageExpanderPluginInterface>
     */
    protected function getProductOfferStorageExpanderPlugins(): array
    {
        return [
            new MerchantProductOfferStorageExpanderPlugin(),
        ];
    }
}

src/Pyz/Zed/ProductOfferStorage/ProductOfferStorageDependencyProvider.php

<?php

namespace Pyz\Zed\ProductOfferStorage;

use Spryker\Zed\MerchantStorage\Communication\Plugin\ProductOfferStorage\MerchantProductOfferStorageFilterPlugin;
use Spryker\Zed\ProductOfferStorage\ProductOfferStorageDependencyProvider as SprykerProductOfferStorageDependencyProvider;

class ProductOfferStorageDependencyProvider extends SprykerProductOfferStorageDependencyProvider
{
    /**
     * @return array<\Spryker\Zed\ProductOfferStorageExtension\Dependency\Plugin\ProductOfferStorageFilterPluginInterface>
     */
    protected function getProductOfferStorageFilterPlugins(): array
    {
        return [
            new MerchantProductOfferStorageFilterPlugin(),
        ];
    }
}
Verification

Make sure that, when you retrieve a product offer from storage, you can see the merchant transfer property.

src/Pyz/Client/UrlStorage/UrlStorageDependencyProvider.php

<?php

namespace Pyz\Client\UrlStorage;

use Spryker\Client\MerchantStorage\Plugin\UrlStorageMerchantMapperPlugin;
use Spryker\Client\UrlStorage\UrlStorageDependencyProvider as SprykerUrlDependencyProvider;

class UrlStorageDependencyProvider extends SprykerUrlDependencyProvider
{
    /**
     * @return array<\Spryker\Client\UrlStorage\Dependency\Plugin\UrlStorageResourceMapperPluginInterface>
     */
    protected function getUrlStorageResourceMapperPlugins()
    {
        return [
            new UrlStorageMerchantMapperPlugin(),
        ];
    }
}
Verification

Make sure the merchant page is accessible at https://mysprykershop/de/merchant/spryker.

  1. Register synchronization and synchronization error queues:

src/Pyz/Client/RabbitMq/RabbitMqConfig.php

<?php

namespace Pyz\Client\RabbitMq;

use Spryker\Client\RabbitMq\RabbitMqConfig as SprykerRabbitMqConfig;
use Spryker\Shared\MerchantStorage\MerchantStorageConfig;

/**
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 */
class RabbitMqConfig extends SprykerRabbitMqConfig
{
    /**
     *  QueueNameFoo, // Queue => QueueNameFoo, (Queue and error queue will be created: QueueNameFoo and QueueNameFoo.error)
     *  QueueNameBar => [
     *       RoutingKeyFoo => QueueNameBaz, // (Additional queues can be defined by several routing keys)
     *   ],
     *
     * @see https://www.rabbitmq.com/tutorials/amqp-concepts.html
     *
     * @return array
     */
    protected function getQueueConfiguration(): array
    {
        return [        
            MerchantStorageConfig::MERCHANT_SYNC_STORAGE_QUEUE,
        ];
    }
}

  1. Configure message processors:
PLUGIN SPECIFICATION PREREQUISITES NAMESPACE
SynchronizationStorageQueueMessageProcessorPlugin Configures all merchant profile messages to synchronize with the key-value store (Redis or Valkey) and marks messages as failed in case of an error. Spryker\Zed\Synchronization\Communication\Plugin\Queue

src/Pyz/Zed/MerchantStorage/MerchantStorageConfig.php

<?php

namespace Pyz\Zed\MerchantStorage;

use Pyz\Zed\Synchronization\SynchronizationConfig;
use Spryker\Zed\MerchantStorage\MerchantStorageConfig as BaseMerchantStorageConfig;

class MerchantStorageConfig extends BaseMerchantStorageConfig
{
    /**
     * @return string|null
     */
    public function getMerchantSynchronizationPoolName(): ?string
    {
        return SynchronizationConfig::DEFAULT_SYNCHRONIZATION_POOL_NAME;
    }
}

src/Pyz/Zed/Queue/QueueDependencyProvider.php

<?php

namespace Pyz\Zed\Queue;

use Spryker\Shared\MerchantStorage\MerchantStorageConfig;
use Spryker\Zed\Kernel\Container;
use Spryker\Zed\Queue\QueueDependencyProvider as SprykerDependencyProvider;
use Spryker\Zed\Synchronization\Communication\Plugin\Queue\SynchronizationSearchQueueMessageProcessorPlugin;

class QueueDependencyProvider extends SprykerDependencyProvider
{
    /**
     * @param \Spryker\Zed\Kernel\Container $container
     *
     * @return array<\Spryker\Zed\Queue\Dependency\Plugin\QueueMessageProcessorPluginInterface>
     */
    protected function getProcessorMessagePlugins(Container $container)
    {
        return [
            MerchantStorageConfig::MERCHANT_SYNC_STORAGE_QUEUE => new SynchronizationStorageQueueMessageProcessorPlugin(),
        ];
    }
}
  1. Set up regenerate and resync features:
PLUGIN SPECIFICATION PREREQUISITES NAMESPACE
MerchantSynchronizationDataPlugin Enables the content of an entire storage table to be synchronized into Storage. Spryker\Zed\MerchantStorage\Communication\Plugin\Synchronization

src/Pyz/Zed/Synchronization/SynchronizationDependencyProvider.php

<?php

namespace Pyz\Zed\Synchronization;

use Spryker\Zed\MerchantStorage\Communication\Plugin\Synchronization\MerchantSynchronizationDataPlugin;
use Spryker\Zed\Synchronization\SynchronizationDependencyProvider as SprykerSynchronizationDependencyProvider;

class SynchronizationDependencyProvider extends SprykerSynchronizationDependencyProvider
{
    /**
     * @return array<\Spryker\Zed\SynchronizationExtension\Dependency\Plugin\SynchronizationDataPluginInterface>
     */
    protected function getSynchronizationDataPlugins(): array
    {
        return [
            new MerchantSynchronizationDataPlugin(),
        ];
    }
}
Verification

Make sure that, when merchant profile entities are created or updated through ORM, they are exported to the key-value store (Redis or Valkey) accordingly.

Configure export to Elastica

This step publishes tables on change (create, edit) to spy_merchant_search and synchronizes the data to Search.

  1. Set up event listeners and publishers by registering the plugins:

src/Pyz/Zed/Publisher/PublisherDependencyProvider.php

<?php

namespace Pyz\Zed\Publisher;

use Spryker\Zed\Publisher\PublisherDependencyProvider as SprykerPublisherDependencyProvider;
use Spryker\Zed\MerchantSearch\Communication\Plugin\Publisher\Merchant\MerchantWritePublisherPlugin;
use Spryker\Zed\MerchantSearch\Communication\Plugin\Publisher\Merchant\MerchantDeletePublisherPlugin;

class PublisherDependencyProvider extends SprykerPublisherDependencyProvider
{
   /**
     * @return array<\Spryker\Zed\PublisherExtension\Dependency\Plugin\PublisherPluginInterface>
     */
    protected function getPublisherPlugins(): array
    {
        return [
            new MerchantWritePublisherPlugin(),
            new MerchantDeletePublisherPlugin(),
        ];
    }
}
  1. Register a synchronization queue:

src/Pyz/Client/RabbitMq/RabbitMqConfig.php

<?php

namespace Pyz\Client\RabbitMq;

use Spryker\Client\RabbitMq\RabbitMqConfig as SprykerRabbitMqConfig;
use Spryker\Shared\MerchantSearch\MerchantSearchConfig;

class RabbitMqConfig extends SprykerRabbitMqConfig
{
    /**
     * @return array
     */
    protected function getQueueConfiguration(): array
    {
        return [
            MerchantSearchConfig::SYNC_SEARCH_MERCHANT,
        ];
    }
}
  1. Configure message processors:
PLUGIN SPECIFICATION PREREQUISITES NAMESPACE
SynchronizationSearchQueueMessageProcessorPlugin Configures merchant messages to sync with the Elastica search and marks messages as failed in case of an error. Spryker\Zed\Synchronization\Communication\Plugin\Queue

src/Pyz/Zed/Queue/QueueDependencyProvider.php

<?php

namespace Pyz\Zed\Queue;

use Spryker\Shared\MerchantSearch\MerchantSearchConfig;
use Spryker\Zed\Kernel\Container;
use Spryker\Zed\Queue\QueueDependencyProvider as SprykerDependencyProvider;
use Spryker\Zed\Synchronization\Communication\Plugin\Queue\SynchronizationSearchQueueMessageProcessorPlugin;

class QueueDependencyProvider extends SprykerDependencyProvider
{
    /**
     * @param \Spryker\Zed\Kernel\Container $container
     *
     * @return array<\Spryker\Zed\Queue\Dependency\Plugin\QueueMessageProcessorPluginInterface>
     */
    protected function getProcessorMessagePlugins(Container $container)
    {
        return [
            MerchantSearchConfig::SYNC_SEARCH_MERCHANT => new SynchronizationSearchQueueMessageProcessorPlugin(),
        ];
    }
}
  1. Set up regenerate and resync features:
PLUGIN SPECIFICATION PREREQUISITES NAMESPACE
MerchantSynchronizationDataBulkRepositoryPlugin Syncs the entire search table content into Search. Spryker\Zed\MerchantSearch\Communication\Plugin\Synchronization

src/Pyz/Zed/Synchronization/SynchronizationDependencyProvider.php

<?php

namespace Pyz\Zed\Synchronization;

use Spryker\Zed\MerchantSearch\Communication\Plugin\Synchronization\MerchantSynchronizationDataBulkRepositoryPlugin;
use Spryker\Zed\Synchronization\SynchronizationDependencyProvider as SprykerSynchronizationDependencyProvider;

class SynchronizationDependencyProvider extends SprykerSynchronizationDependencyProvider
{
    /**
     * @return array<\Spryker\Zed\SynchronizationExtension\Dependency\Plugin\SynchronizationDataPluginInterface>
     */
    protected function getSynchronizationDataPlugins(): array
    {
        return [
            new MerchantSynchronizationDataBulkRepositoryPlugin(),
        ];
    }
}
  1. Configure a synchronization pool name:

src/Pyz/Zed/MerchantSearch/MerchantSearchConfig.php

<?php

namespace Pyz\Zed\MerchantSearch;

use Pyz\Zed\Synchronization\SynchronizationConfig;
use Spryker\Zed\MerchantSearch\MerchantSearchConfig as SprykerMerchantSearchConfig;

class MerchantSearchConfig extends SprykerMerchantSearchConfig
{
    /**
     * @return string|null
     */
    public function getMerchantSearchSynchronizationPoolName(): ?string
    {
        return SynchronizationConfig::DEFAULT_SYNCHRONIZATION_POOL_NAME;
    }
}
  1. Set up result formatters:
PLUGIN SPECIFICATION PREREQUISITES NAMESPACE
MerchantSearchResultFormatterPlugin Maps raw data from Elasticsearch to MerchantSearchCollectionTransfer. Spryker\Client\MerchantSearch\Plugin\Elasticsearch\ResultFormatter

src/Pyz/Client/MerchantSearch/MerchantSearchDependencyProvider.php

<?php

namespace Pyz\Client\MerchantSearch;

use Spryker\Client\MerchantSearch\MerchantSearchDependencyProvider as SprykerMerchantSearchDependencyProvider;
use Spryker\Client\MerchantSearch\Plugin\Elasticsearch\ResultFormatter\MerchantSearchResultFormatterPlugin;

class MerchantSearchDependencyProvider extends SprykerMerchantSearchDependencyProvider
{
    /**
     * @return array<\Spryker\Client\SearchExtension\Dependency\Plugin\ResultFormatterPluginInterface>
     */
    protected function getMerchantSearchResultFormatterPlugins(): array
    {
        return [
            new MerchantSearchResultFormatterPlugin(),
        ];
    }
}
  1. Set up query expanders:
PLUGIN SPECIFICATION PREREQUISITES NAMESPACE
PaginatedMerchantSearchQueryExpanderPlugin Allows using pagination for the merchant search. Spryker\Client\MerchantSearch\Plugin\Elasticsearch\Query
StoreQueryExpanderPlugin Allows searching to filter out merchants that don’t belong to the current store. Spryker\Client\SearchElasticsearch\Plugin\QueryExpander

src/Pyz/Client/MerchantSearch/MerchantSearchDependencyProvider.php

<?php

namespace Pyz\Client\MerchantSearch;

use Spryker\Client\MerchantSearch\MerchantSearchDependencyProvider as SprykerMerchantSearchDependencyProvider;
use Spryker\Client\MerchantSearch\Plugin\Elasticsearch\Query\PaginatedMerchantSearchQueryExpanderPlugin;
use Spryker\Client\SearchElasticsearch\Plugin\QueryExpander\StoreQueryExpanderPlugin;

class MerchantSearchDependencyProvider extends SprykerMerchantSearchDependencyProvider
{
    /**
     * @return array<\Spryker\Client\SearchExtension\Dependency\Plugin\QueryExpanderPluginInterface>
     */
    protected function getMerchantSearchQueryExpanderPlugins(): array
    {
        return [
            new PaginatedMerchantSearchQueryExpanderPlugin(),
            new StoreQueryExpanderPlugin(),
        ];
    }
}
  1. Add the merchant source to the supported search sources:

src/Pyz/Shared/SearchElasticsearch/SearchElasticsearchConfig.php

<?php

namespace Pyz\Shared\SearchElasticsearch;

use Spryker\Shared\SearchElasticsearch\SearchElasticsearchConfig as SprykerSearchElasticsearchConfig;

class SearchElasticsearchConfig extends SprykerSearchElasticsearchConfig
{
    protected const SUPPORTED_SOURCE_IDENTIFIERS = [
        'merchant',
    ];
}
Verification

Make sure that, when merchant entities are created or updated through ORM, they’re exported to Elastica accordingly.

TARGET ENTITY EXAMPLE OF EXPECTED DATA IDENTIFIER
Merchant merchant:1
Example of the expected data fragment

{
 "idMerchant": 1,
 "name": "Sony Experts",
 "registrationNumber": "HYY 134306",
 "email": "[email protected]",
 "status": "approved",
 "isActive": true,
 "merchantReference": "MER000006",
 "fkStateMachineProcess": 1,
 "storeRelation": {
   "idEntity": 1,
   "idStores": [
     1
   ],
   "stores": [
     {
       "availableLocaleIsoCodes": [],
       "queuePools": [],
       "storesWithSharedPersistence": [],
       "idStore": 1,
       "name": "DE",
       "defaultCurrencyIsoCode": null,
       "availableCurrencyIsoCodes": [],
       "selectedCurrencyIsoCode": null,
       "timezone": null,
       "countries": []
     }
   ]
 },
 "addressCollection": null,
 "merchantProfile": null,
 "urlCollection": [
   {
     "url": "/de/merchant/sony-experts",
     "resourceType": null,
     "resourceId": null,
     "fkLocale": 46,
     "idUrl": 505,
     "fkResourceCategorynode": null,
     "fkRedirect": null,
     "fkResourcePage": null,
     "fkResourceRedirect": null,
     "fkResourceMerchant": 1,
     "urlPrefix": null,
     "localeName": "de_DE",
     "fkResourceProductAbstract": null,
     "fkResourceProductSet": null,
     "itemType": null,
     "itemId": null,
     "fkProductAbstract": null,
     "fkCategorynode": null,
     "fkPage": null
   },
   {
     "url": "/en/merchant/sony-experts",
     "resourceType": null,
     "resourceId": null,
     "fkLocale": 66,
     "idUrl": 506,
     "fkResourceCategorynode": null,
     "fkRedirect": null,
     "fkResourcePage": null,
     "fkResourceRedirect": null,
     "fkResourceMerchant": 1,
     "urlPrefix": null,
     "localeName": "en_US",
     "fkResourceProductAbstract": null,
     "fkResourceProductSet": null,
     "itemType": null,
     "itemId": null,
     "fkProductAbstract": null,
     "fkCategorynode": null,
     "fkPage": null
   }
 ],
 "categories": [
   {
     "idCategory": 2,
     "categoryKey": "cameras-and-camcorder",
     "isActive": true,
     "isInMenu": true,
     "isClickable": true,
     "isSearchable": true,
     "name": null,
     "url": null,
     "imageName": null,
     "categoryImageName": null,
     "metaTitle": null,
     "metaDescription": null,
     "metaKeywords": null,
     "fkCategoryTemplate": 1,
     "idCmsBlocks": [],
     "categoryNode": null,
     "nodeCollection": null,
     "parentCategoryNode": null,
     "localizedAttributes": [
       {
         "name": "Kameras & Camcorders",
         "url": null,
         "metaTitle": "Kameras & Camcorders",
         "metaDescription": "Kameras & Camcorders",
         "metaKeywords": "Kameras & Camcorders",
         "locale": {
           "idLocale": 46,
           "localeName": "de_DE",
           "name": null,
           "isActive": true
         },
         "image": null
       },
       {
         "name": "Cameras & Camcordersshhhhjjj",
         "url": null,
         "metaTitle": "Cameras & Camcorders",
         "metaDescription": "Cameras & Camcorders",
         "metaKeywords": "Cameras & Camcorders",
         "locale": {
           "idLocale": 66,
           "localeName": "en_US",
           "name": null,
           "isActive": true
         },
         "image": null
       }
     ],
     "extraParents": [],
     "imageSets": []
   }
 ],
 "stocks": [
   {
     "idStock": 7,
     "name": "Sony Experts MER000006 Warehouse 1",
     "isActive": true,
     "storeRelation": null
   }
 ]
}