Shopware Setup Guide

Add a chat assistant to your Shopware 6 store with automatic product sync.

You're in the developer setup guide. Looking for an overview of what Emporiqa does for your Shopware store? See the integration page.

See integration page

Fast Start

Install the plugin, paste two credentials, run one sync. Your chat widget goes live on your storefront.

What you'll need

  • Admin access to your Shopware 6 store (version 6.6 or 6.7) running PHP 8.2 or newer
  • An Emporiqa account — create a free sandbox if you don't have one yet
  • A running message consumer (bin/console messenger:consume async) so webhook events are delivered

First, install the plugin. The easiest path is the Shopware admin: go to Extensions → Store, search for Emporiqa, then click Install and Activate. For self-hosted shops, install via Composer from packages.shopware.com:

composer require store.shopware.com/emporiqaintegration
bin/console plugin:refresh
bin/console plugin:install --activate EmporiqaIntegration
bin/console theme:compile
bin/console cache:clear

Theme compilation and cache clearing are handled automatically when you install through the Extension Store.

1

Enter your credentials

Open Extensions → My extensions → Emporiqa → Configuration. Paste your Store ID and Webhook Secret — both come from your Emporiqa dashboard under Settings → Store Integration → Integration Overview. Every setting can be overridden per sales channel.

Shopware Administration showing the Emporiqa Settings tab with Connection card, Store ID, Webhook Secret, and Test Connection button
Settings → Emporiqa → Settings tab
2

Run the initial sync

The plugin adds a dedicated Emporiqa module in the Shopware Administration. Open it, click Test Connection to verify the plugin can reach the Emporiqa webhook endpoint, then use the Sync Dashboard to send products, pages, or both. Sync events go through Shopware's message queue, so make sure a consumer is running with bin/console messenger:consume async. Larger catalogs are split into batches automatically (default 50 items per batch).

Shopware Administration Emporiqa Sync tab with Sync Dashboard showing product and page counts per channel, Sync Products, Sync Pages, and Sync All actions
Sync tab with Sync Dashboard and Sync Products/Pages/All actions
3

Verify the chat widget

Open your storefront. The chat bubble appears in the bottom-right corner. Click it, ask a product question, and watch the salesperson answer from your catalog. Channel, currency, and full locale are detected automatically from the active sales channel.

Shopper describes what they want, the online salesperson recommends the right product from your catalog
Chat widget on the Emporiqa demo store — the same widget runs on your Shopware storefront.

You're live

  • New products and pages sync automatically when you save them
  • Customers can ask about products, policies, and their orders
  • Add-to-cart in chat; customers proceed to your store checkout

Need to customize sync behavior, decorate a service, or run sync from the CLI?

See Developer Docs

Developer Documentation

Architecture, configuration reference, webhook payload schema, service decoration, CLI commands, and extension events.

Architecture

The plugin uses Shopware event subscribers (ProductSubscriber, LandingPageSubscriber, CategorySubscriber, OrderSubscriber) to react to write and delete events. Webhook events are dispatched through Shopware's message queue (Symfony Messenger) so the storefront response is never blocked on outbound HTTP.

Storefront sales channels are auto-detected and mapped to Emporiqa channel keys (slugified from channel names). Headless and API channels are excluded. All translations and currencies for a single product or page consolidate into one webhook event in the format {channel: {language: value}}, matching every other Emporiqa integration.

Transient failures (HTTP 429) are re-queued with a 65-second delay, up to 5 retries. Other failures fall back to Shopware's standard message queue retry mechanism. Full syncs split the catalog into configurable batches (default 50, max 200) to keep memory usage bounded.

A message consumer must be running for webhook events to leave the queue: bin/console messenger:consume async.

Requirements

Shopware 6 >= 6.6.0, < 6.8.0
Shopware Storefront >= 6.6.0, < 6.8.0
PHP 8.2 or higher
Composer package store.shopware.com/emporiqaintegration
Emporiqa account Free sandbox or paid subscription

Configuration Reference

All settings live at Extensions → My extensions → Emporiqa → Configuration. Every setting can be overridden per sales channel.

Connection Settings

Setting Description
storeId Your Emporiqa store identifier (Settings → Store Integration → Integration Overview).
webhookSecret Shared secret used to sign webhook payloads with HMAC-SHA256.

Sync Settings

Setting Default Description
syncProducts true Enable automatic product sync on create / update / delete.
syncPages true Enable CMS landing page sync.

Order Tracking Settings

Setting Default Description
orderTrackingEnabled true Enables the inbound endpoint that Emporiqa calls to look up order status.
orderRequireEmail true When enabled, Emporiqa must provide a matching customer email to look up order status.

Advanced Settings

Most stores don't need to change these.

Setting Default Description
webhookUrl https://emporiqa.com/webhooks/sync/ Base URL for the Emporiqa webhook endpoint. Only change for custom instances.
batchSize 50 Items per webhook batch during full sync. Maximum 200.
taxDisplay gross How prices are sent: gross (incl. tax), net (excl. tax), or both.
cartEnabled true Enables the storefront cart endpoints used by the chat widget.

Dashboard-Managed Settings

These are managed through the Emporiqa admin module UI, not the raw plugin configuration page.

Setting Description
Brand Attribute Property group ID used as brand source. Defaults to the product manufacturer.
Order Completed States JSON array of state technical names that trigger the order.completed webhook event.

Features

Real-time Webhooks

Products, landing pages, categories, and orders sync via subscribers on write and delete events. Outbound delivery runs through Symfony Messenger.

Sales Channel Detection

Storefront sales channels are auto-mapped to Emporiqa channel keys (slugified channel names). Headless and API channels are excluded.

Multi-language

All languages from your sales channel domains are included in a single consolidated payload per product or page.

Multi-currency & Tax Modes

Products include prices for every currency configured per sales channel. Choose gross, net, or both via the taxDisplay setting.

In-chat Cart

JSON API under /emporiqa/api/cart for add, update, remove, clear, and checkout. Product links use SEO URLs.

Admin Dashboard

Dedicated admin module: test connection, configure brand source and order states, preview payloads, and trigger syncs per channel.

Conversion Tracking

Order placement and configurable completion events are sent to Emporiqa for revenue attribution to chat sessions.

Async Delivery & Retries

All product and order webhooks dispatch through the Shopware message queue. 429 responses re-queue with a 65-second delay, up to 5 retries.

Webhook Payload

Each product (or variant) and page is sent as a single webhook event containing all sales channels, languages, and currencies. Parent products include their variants as separate entries.

Product Event

{
  "identification_number": "product-UUID",
  "sku": "SW-001",
  "channels": ["storefront", "b2b"],
  "names": {
    "storefront": {"en": "Running Shoes", "de": "Laufschuhe"},
    "b2b": {"en": "Running Shoes"}
  },
  "descriptions": {
    "storefront": {"en": "Lightweight running shoes...", "de": "Leichte Laufschuhe..."}
  },
  "links": {
    "storefront": {"en": "https://shop.com/running-shoes", "de": "https://shop.de/laufschuhe"}
  },
  "categories": {
    "storefront": {"en": ["Sports > Footwear > Running"], "de": ["Sport > Schuhe > Laufen"]}
  },
  "brands": {"storefront": "Acme"},
  "prices": {
    "storefront": [
      {"currency": "EUR", "current_price": 89.99, "regular_price": 99.99},
      {"currency": "USD", "current_price": 94.99, "regular_price": 109.99}
    ]
  },
  "availability_statuses": {"storefront": "available"},
  "stock_quantities": {"storefront": 42},
  "images": {"storefront": ["https://shop.com/media/shoes.jpg"]},
  "attributes": {
    "storefront": {"en": {"Color": "Blue", "Size": "42"}, "de": {"Farbe": "Blau", "Größe": "42"}}
  },
  "parent_sku": null,
  "is_parent": true,
  "variation_attributes": {"storefront": {"en": ["Color", "Size"]}},
  "sync_session_id": "shopware-products-abc123"
}

Field Structure

Type Pattern Fields
Translatable {channel: {lang: value}} names, descriptions, links, categories, attributes, variation_attributes
Shared {channel: value} brands, prices, images, availability_statuses, stock_quantities
Flat Direct value identification_number, sku, channels, is_parent, parent_sku, sync_session_id

When taxDisplay=both, each price entry also includes price_incl_tax and price_excl_tax. Identifiers use product-<uuid> for parents and variation-<uuid> for variants.

Customization & Events

Every core service is registered behind an interface and can be replaced via Shopware's standard service decoration mechanism. Symfony events are dispatched at key points in the sync lifecycle for lighter-weight extensions.

Service Interfaces

Interface Responsibility
ConfigServiceInterface Read plugin configuration values per sales channel.
WebhookClientInterface Send HMAC-signed HTTP requests to the Emporiqa webhook endpoint.
ProductFormatterInterface Transform ProductEntity objects into the consolidated payload.
CmsPageFormatterInterface Transform LandingPageEntity objects into the consolidated payload.
ChannelResolverInterface Map Shopware sales channels to Emporiqa channel keys.
SyncServiceInterface Orchestrate full product and page syncs and manage sync sessions.

All interfaces live in the Emporiqa\ShopwarePlugin\Service namespace.

Example: decorate the product formatter

<!-- MyPlugin/src/Resources/config/services.xml -->
<service id="MyPlugin\Service\CustomProductFormatter"
         decorates="Emporiqa\ShopwarePlugin\Service\ProductFormatter">
    <argument type="service" id="MyPlugin\Service\CustomProductFormatter.inner"/>
</service>
<?php
declare(strict_types=1);

namespace MyPlugin\Service;

use Emporiqa\ShopwarePlugin\Service\ProductFormatterInterface;
use Shopware\Core\Content\Product\ProductEntity;

class CustomProductFormatter implements ProductFormatterInterface
{
    public function __construct(
        private readonly ProductFormatterInterface $inner,
    ) {}

    public function formatProduct(
        ProductEntity $product,
        array $channelContexts,
        ?string $syncSessionId = null,
    ): array {
        $items = $this->inner->formatProduct($product, $channelContexts, $syncSessionId);

        foreach ($items as &$item) {
            $item['custom_field'] = 'custom_value';
        }

        return $items;
    }

    public function formatProductDelete(string $productId): array
    {
        return $this->inner->formatProductDelete($productId);
    }
}

Extension Events

The plugin dispatches Symfony events at key points in the sync and formatting lifecycle. Listen to these in your own plugin to filter, enrich, or log data without decorating a full service.

Event When Mutable via
PreSyncEvent Before a full sync starts setChannelContexts()
PostSyncEvent After a full sync completes Read-only result data
PostProductFormatEvent After a product is formatted setFormattedItems()
PostPageFormatEvent After a CMS page is formatted setFormattedData()
PostOrderFormatEvent After an order payload is built setEventData()

All event classes live in the Emporiqa\ShopwarePlugin\Event namespace.

CLI Commands

All sync operations available in the admin dashboard can also be run from the Shopware CLI. Each sync command supports a --dry-run flag that simulates the sync without sending any webhook requests.

Command Description
emporiqa:sync:products Synchronize the full product catalog.
emporiqa:sync:pages Synchronize all CMS landing pages.
emporiqa:sync:all Run both product and page syncs in a single command.
emporiqa:test-connection Verify the plugin can reach the Emporiqa webhook endpoint.
bin/console emporiqa:sync:products
bin/console emporiqa:sync:products --dry-run

bin/console emporiqa:sync:pages
bin/console emporiqa:sync:all

bin/console emporiqa:test-connection

Administration API equivalents

Endpoint Method Description
/api/_action/emporiqa/sync POST Trigger a full sync. Body: {"entity": "products"}, {"entity": "pages"}, or omit for all.
/api/_action/emporiqa/test-connection POST Test the webhook connection.
/api/_action/emporiqa/sync-overview POST Return product/page counts, languages, channels, and configuration status.
/api/_action/emporiqa/data-preview POST Return a sample formatted product and page payload.
/api/_action/emporiqa/sales-channels POST Return all active sales channels with domain details.
/api/_action/emporiqa/property-groups POST Return all property groups for brand source selection.
/api/_action/emporiqa/order-states POST Return all order and transaction state machine states.
/api/_action/emporiqa/save-settings POST Save dashboard-managed settings (channel mapping, brand attribute, order states).

Order Tracking

Emporiqa can look up order status on behalf of customers during chat conversations. The plugin exposes a signed inbound endpoint that the Emporiqa backend calls when a customer asks about their order.

Flow

  1. Customer asks "Where is my order #10001?" in the chat.
  2. Emporiqa sends an HMAC-SHA256 signed POST to your store with the order identifier and timestamp.
  3. The plugin verifies the signature, looks up the order, optionally checks the customer email, and returns the order status, totals, addresses, and items.
  4. The salesperson presents the order information to the customer.

Endpoint

POST /emporiqa/api/order/tracking

Setup

The endpoint is active whenever orderTrackingEnabled is true. To enable order lookup from chat, copy the endpoint URL from the Emporiqa admin module and paste it into your Emporiqa dashboard at Settings → Store Integration → Order Tracking:

https://your-store.com/emporiqa/api/order/tracking

Requests are authenticated using the same webhookSecret via the X-Emporiqa-Signature header. Requests with a timestamp older than 5 minutes are rejected (HTTP 401). When orderRequireEmail is enabled, the request must include a matching customer email or it returns HTTP 403.

Order tracking is optional. Without the dashboard URL configured, order questions route to the Customer Support agent instead.

Troubleshooting

Products are not syncing automatically

  • Verify that syncProducts is enabled in the plugin configuration.
  • Make sure the message consumer is running: bin/console messenger:consume async.
  • Check the failed message queue: bin/console messenger:failed:show.

Widget does not appear on the storefront

  • Confirm that Store ID and Webhook Secret are set in the plugin configuration.
  • Rebuild the storefront theme: bin/console theme:compile followed by bin/console cache:clear.
  • Check the browser console for JavaScript errors.

Test connection fails

  • Check that the webhookUrl is reachable from your server.
  • Verify that Store ID and Webhook Secret match the values in your Emporiqa dashboard.
  • Run the CLI test command for verbose output: bin/console emporiqa:test-connection -vvv.

Cart API returns "Cart API is disabled"

  • The cartEnabled setting is set to false. Enable it in Extensions → My extensions → Emporiqa → Configuration.

Order tracking returns 401 or 403

  • 401: The X-Emporiqa-Signature header is missing or invalid, or the request timestamp is older than 5 minutes.
  • 403: orderRequireEmail is enabled and the request does not include a matching verification_fields.email.

Sync times out on large catalogs

  • Reduce batchSize in the plugin configuration to lower memory per batch.
  • Prefer the CLI command for large catalogs: bin/console emporiqa:sync:products.
  • Clear caches after configuration changes: bin/console cache:clear.

Related Articles

Need Help?

Having trouble with the integration? Our team is here to help.

Contact Support