Install the Buy Box feature

Edit on GitHub

Use this guide to install the Buy Box feature for marketplace scenarios.

Prerequisites

Install the following required features:

NAME VERSION INSTALLATION GUIDE
Spryker Core latest Install the Spryker Core feature
Product latest Install the Product feature
Cart latest Install the Cart feature
Marketplace Product latest Install the Marketplace Product feature
Marketplace Product Offer latest Install the Marketplace Product Offer feature
Marketplace Inventory Management latest Install the Marketplace Inventory Management feature
Marketplace Merchant latest Install the Marketplace Merchant feature

1. Install the required modules

Install the required modules by using Composer:

composer require spryker-feature/buy-box:"latest" --update-with-dependencies
Verification

Make sure the following modules have been installed:

MODULE EXPECTED DIRECTORY
BuyBox vendor/spryker-feature/buy-box

2. Set up configuration

Add the following configuration to your project:

src/Pyz/Yves/BuyBox/BuyBoxConfig.php

<?php

namespace Pyz\Yves\BuyBox;

use SprykerFeature\Yves\BuyBox\BuyBoxConfig as SprykerFeatureBuyBoxConfig;

class BuyBoxConfig extends SprykerFeatureBuyBoxConfig
{
    /**
     * @return string
     */
    public function getSortingStrategy(): string
    {
        return static::SORT_BY_PRICE;
    }
}
Configuration options

getSortingStrategy(): Returns the sorting strategy for Buy Box offers. Options:

  • static::SORT_BY_PRICE - Sorts by lowest to highest price (default).
  • static::SORT_BY_STOCK - Sorts by highest to lowest stock (requires the Marketplace Inventory Management feature).

3. Set up transfer objects

Generate the transfer objects:

console transfer:generate
Verification

Make sure the following changes have been applied to the transfer objects:

TRANSFER TYPE EVENT PATH
BuyBoxProduct class Created src/Generated/Shared/Transfer/BuyBoxProductTransfer
ProductOfferStorageCriteria class Created src/Generated/Shared/Transfer/ProductOfferStorageCriteriaTransfer
ProductView class Extended src/Generated/Shared/Transfer/ProductViewTransfer
MerchantStorageCriteria class Created src/Generated/Shared/Transfer/MerchantStorageCriteriaTransfer
PriceProductFilter class Extended src/Generated/Shared/Transfer/PriceProductFilterTransfer
MerchantStorage class Extended src/Generated/Shared/Transfer/MerchantStorageTransfer

4. Set up behavior

Register the following plugin:

src/Pyz/Yves/ShopApplication/ShopApplicationDependencyProvider.php

<?php

namespace Pyz\Yves\ShopApplication;

use SprykerFeature\Yves\BuyBox\Widget\BuyBoxWidget;
use SprykerShop\Yves\ShopApplication\ShopApplicationDependencyProvider as SprykerShopApplicationDependencyProvider;

class ShopApplicationDependencyProvider extends SprykerShopApplicationDependencyProvider
{
    /**
     * @return array<string>
     */
    protected function getGlobalWidgets(): array
    {
        return [
            BuyBoxWidget::class,
        ];
    }
}
Verification

Make sure that BuyBoxWidget is registered by checking that the buy box appears on product detail pages in marketplace mode with multiple merchant offers.

5. Set up templates

Integrate the BuyBoxWidget into the product detail page template.

src/Pyz/Yves/ProductDetailPage/Theme/default/components/molecules/product-configurator/product-configurator.twig


{% extends molecule('product-configurator', '@SprykerShop:ProductDetailPage') %}

{% set isProductConcrete = data.product.idProductConcrete is not empty %}
{% set buyBoxWidget = findWidget('BuyBoxWidget', [data.product, app.request]) %}
{% set productOffersCount = buyBoxWidget.products | length %}
{% set showProductAvailability = isProductConcrete and productOffersCount == 0 %}
{% set isAvailable = isProductConcrete and (data.product.available or productOffersCount) %}

{% block body %}
    {# ... existing code ... #}

    {% widget 'AddToCartFormWidget' args [config, data.product, isDisabled, options] with {
        data: {
            isService: sspServiceDetectorWidget and sspServiceDetectorWidget.isService,
        },
        embed: {
            showProductAvailability: showProductAvailability,
            buyBoxWidget: buyBoxWidget,
        },
    } only %}
        {% block embeddedData %}
            {# ... existing code ... #}

            {% if not shipmentTypeServicePointSelectorWidget or not shipmentTypeServicePointSelectorWidget.hasShipmentTypeWithRequiredLocation %}
                <div class="spacing-bottom spacing-bottom--bigger">
                    {% widget embed.buyBoxWidget %}
                        {% block content %}
                            {{ parent() }}
                        {% endblock %}
                    {% endwidget %}
                </div>
            {% endif %}

            {# ... rest of the template ... #}
        {% endblock %}
    {% endwidget %}

    {# ... rest of the template ... #}
{% endblock %}

Template change summary

This template change:

  • Calculates productOffersCount by using the BuyBoxWidget.
  • Sets showProductAvailability so availability displays only when no product offers exist.
  • Passes buyBoxWidget through the embed context to render it within AddToCartFormWidget.
  • Replaces the default merchant product widgets with the unified BuyBoxWidget display.
Verification

Make sure the Buy Box displays correctly on product detail pages:

  • When multiple merchant offers exist, the Buy Box shows all available offers.
  • Each offer displays merchant information and price.
  • You can select different merchant offers.
  • When no product offers exist, availability information displays instead.

6. Import glossary data

Import glossary keys for buy box translations:

data/import/common/common/glossary.csv

>buy_box.sold_by,"Sold by",en_US
buy_box.sold_by,"Verkauft von",de_DE
buy_box.view_merchant,"View seller",en_US
buy_box.view_merchant,"Händler ansehen",de_DE

Run the data import:

console data:import glossary
Verification

Make sure the glossary keys have been imported by checking the spy_glossary_key and spy_glossary_translation tables. Verify that the buy box displays the correct translations on the storefront.

7. Set up frontend

Build the frontend to include the new styles and assets:

console frontend:yves:build

8. Optional: Add stock-based sorting and availability per offer

To enable stock-based sorting and show availability per merchant offer, install the Product Availability Display feature and configure the integration.

Install Product Availability Display feature

Follow the Install the Product Availability Display feature guide to install the availability modules.

Add availability to product offers

Register the plugin that adds availability data to product offers:

src/Pyz/Client/ProductOfferStorage/ProductOfferStorageDependencyProvider.php

<?php

namespace Pyz\Client\ProductOfferStorage;

use Spryker\Client\ProductOfferAvailabilityStorage\Plugin\ProductOfferStorage\ProductOfferAvailabilityProductOfferStorageBulkExpanderPlugin;
use Spryker\Client\ProductOfferStorage\ProductOfferStorageDependencyProvider as SprykerProductOfferStorageDependencyProvider;

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

Make sure that ProductOfferAvailabilityProductOfferStorageBulkExpanderPlugin is registered by viewing a product with multiple merchant offers and verifying that each offer displays its own availability information.

Configure stock-based sorting

To sort offers by stock instead of price, update your Buy Box configuration (from step 2) to use SORT_BY_STOCK:

src/Pyz/Yves/BuyBox/BuyBoxConfig.php

public function getSortingStrategy(): string
{
    return static::SORT_BY_STOCK; // Sort by highest to lowest stock
}

This enables stock-aware Buy Box functionality with per-offer availability and stock-based sorting.