Logo Dark
  • E-Commerce

    See where your store can improve.

    Get Your Free Audit
    Frame 1321315514

    Shopware

    Platinum Partner, now in the US

    More
    Frame 1321315514 1

    Shopify

    Fast to launch, built to scale

    More
    Frame 1321315514 19

    Magento

    Complex catalogs and B2B

    Coming soon
    Frame 1321315514 18

    WooCommerce

    Flexible commerce for growing businesses

    Coming soon
    Frame 1321315514 2

    Migrations

    Move platforms without disrupting revenue

    More
    Frame 1321315514 3

    Integrations

    Payments, tax, fulfillment, marketing

    More
    Frame 1618873659

    Start your Shopware migration with us.

    Learn more
  • Software & AI

    See where your store can improve.

    Get Your Free Audit
    Frame 1321315514 4

    Software Development

    Platforms and portals, systems connected

    Coming soon
    Frame 1321315514 5

    App Development

    Web and mobile apps, API-first

    Coming soon
    Frame 1321315514 6

    AI Development

    Models connected, data enriched, assistants

    Coming soon
    Frame 1321315514 7

    Replatforming

    Switch platforms without losing revenue

    More
    Frame 1321315514 8

    All Integrations

    Payments, tax, fulfillment, marketing

    More
    Frame 1618873659 1

    Discover our latest Shopware plugin. FreeShip for Shopware 6

    Explore the plugin
  • Solutions

    See where your store can improve.

    Get Your Free Audit

    Further links

    Frame 1321315514 16 GitHub Arrow Up Right Frame 1321315514 17 Shopware Store Arrow Up Right
    Frame 1321315514 10

    Shopware Plugins

    Extensions built by our team

    More
    Frame 1321315514 11

    Optimizely Integrationen

    Campaigns, automation and customer engagement

    More
    Frame 1321315514 12

    Lavet

    Migration and integration platform

    More
    Frame 1321315514 13

    StatHubs

    All store metrics in one dashboard

    Coming soon
    Frame 1321315514 21

    Pathway

    By Boldest, in partnership with solution25

    Coming soon
    Frame 1618873659 2

    Discover our Optimizely Campaign plugin.

    Explore the plugin
  • Company

    See where your store can improve.

    Get Your Free Audit

    About

    Events & Summit

    Resources

    Careers

    Frame 1618873659 3

    Built by people who know commerce.

    Chevron Right White
  • Contact
  • Language: EN

    Select Language

    • DE
    • EN
+1 929-264-76 02
  • DE
  • Free consultation
    1. Home /
    2. Webhooks in Shopware 6 – Event System Integration Guide
    Web Hooks Integration Shopware 2048x1582 1
    13 June 2025

    Webhooks in Shopware 6 – Event System Integration Guide

    
                        

    1. Introduction

    Shopware 6 offers two different ways of reacting to something happening in a shop, and they are easy to confuse. One is the internal PHP event system, which plugins hook into and which runs inside the Shopware process. The other is webhooks, which are part of the App System and notify an external service over HTTP.

    Choosing the wrong one costs time. A plugin subscriber cannot run on a Shopware Cloud instance, and a webhook cannot change what happens during a request. This guide explains what each mechanism does, how a webhook is registered and secured, and which behaviours are documented versus which you should not rely on.

    All technical details below refer to the official Shopware developer documentation. Version-dependent features are marked with the release they were introduced in.

    2. Webhooks and the event system explained

    Shopware plugins run inside the shop. They register a subscriber that implements EventSubscriberInterface, tag it with kernel.event_subscriber, and receive events synchronously while the request is still being processed. Because the subscriber holds the event object, it can influence what happens next: adjust a price, block a write, change what the storefront renders.

    Apps run outside the shop. Shopware communicates with them exclusively over HTTP, and webhooks are how the shop tells the app that something happened. The app receives a POST request after the fact and reacts by calling back into the Admin API. It cannot alter the process that triggered it.

    The practical differences

    • Timing: plugin events are synchronous; webhooks are queued and delivered asynchronously.
    • Scope: a plugin can subscribe to any dispatched event. A webhook can only subscribe to the curated set of hookable events listed in Shopware’s webhook events reference.
    • Language: plugins are PHP. An app can be written in anything that speaks HTTP.
    • Hosting: plugins require access to the shop’s filesystem. Webhooks are the only route available on Shopware Cloud.

    A useful rule of thumb: if the logic has to run during the request and change its outcome, it belongs in a plugin. If it reacts after the fact and lives on your own infrastructure, it belongs in an app with webhooks.

    3. Requirements

    Before the first webhook fires, four things need to be in place.

    A registered app

    Webhooks belong to an app, not to a plugin. The app is defined by a manifest.xml and completes a registration handshake with the shop, during which your app generates and stores a per-shop secret. That secret is what later signs every webhook request.

    A running message queue consumer

    Webhook delivery is queued through Shopware’s message queue. If no consumer is running, messages are written but never sent, and no error appears in the storefront. This is the single most common reason a correctly configured webhook appears to do nothing.

    A publicly reachable HTTPS endpoint

    Shopware posts to the URL declared in the manifest. It must be reachable from the shop server and should terminate TLS. For local development, a tunnelling service is required so that the shop can reach your machine.

    Matching ACL permissions

    Most webhook events require a corresponding permission in the manifest. Subscribing to order.written without declaring order:read will fail validation. Shopware has enforced webhook permission validation since 6.3.5.0.

    4. Registering a webhook in manifest.xml

    There is no webhook plugin to install. Webhooks are declared directly in the app manifest, inside a <webhooks> block:

    <webhooks>
        <webhook name="product-changed"
                 url="https://example.com/event/product-changed"
                 event="product.written"/>
    </webhooks>

    Three attributes are required. name must be unique within the manifest, url is the endpoint Shopware posts to, and event is the identifier of the event you want to receive.

    Which events are available

    Only events that Shopware marks as hookable can be used. The documented set covers the areas most integrations need:

    • Orders and checkout: checkout.order.placed, order.written, order.deleted
    • Entities: product.written, product.deleted, customer.written, category.written, media.written and their counterparts
    • Customer accounts: checkout.customer.register, checkout.customer.login, checkout.customer.logout, customer.recovery.request
    • State machine transitions: state_enter.order.state.completed, state_enter.order_transaction.state.paid, state_enter.order_delivery.state.shipped and the matching state_leave events
    • App lifecycle: app.installed, app.activated, app.deactivated, app.deleted, plus shopware.updated

    Limiting writes to the live version

    Since Shopware 6.5.7.0, a webhook can carry onlyLiveVersion="true". Without it, an order.written webhook also fires for versioned drafts created while an order is being edited in the administration, which usually is not what an integration wants:

    <webhook name="order-created"
             url="https://example.com/event/order-created"
             event="order.written"
             onlyLiveVersion="true"/>

    The attribute is only evaluated for entity-written events.

    5. What Shopware actually sends

    The request body is JSON and always has the same three top-level keys:

    {
      "data": {
        "payload": [
          {
            "entity": "product",
            "operation": "delete",
            "primaryKey": "7b04ebe416db4ebc93de4d791325e1d9",
            "updatedFields": []
          }
        ],
        "event": "product.written"
      },
      "source": {
        "url": "http://localhost:8000",
        "appVersion": "0.0.1",
        "shopId": "dgrH7nLU6tlE",
        "eventId": "7b04ebe416db4ebc93de4d791325e1d9"
      },
      "timestamp": 123123123
    }

    The part that surprises people

    For entity-written events the payload does not contain the full entity. Shopware states the reason plainly: because delivery is asynchronous, a complete entity might already be outdated by the time it arrives. What you get is the primaryKey, and the expected pattern is to fetch the current state through the Admin API.

    Integrations that treat the payload as the source of truth will eventually write stale data back into a connected system. This is worth deciding before the first line of code, not after.

    Fields worth knowing

    • source.shopId identifies the shop and stays constant for its lifetime.
    • source.eventId stays the same across retries, which makes it the natural key for deduplication.
    • timestamp is the time the webhook was handled and is available from 6.4.1.0 onwards.

    Shopware also sends a sw-version header from 6.4.1.0, and sw-context-language plus sw-user-language from 6.4.5.0.

    6. Verifying the signature

    Every webhook request carries a shopware-shop-signature header. It contains a SHA-256 HMAC of the raw request body, keyed with the shop secret your app generated during registration. An endpoint that skips this check accepts anything anyone posts to it.

    Two secrets, two headers

    The App System uses two different secrets, and mixing them up is a common source of failed verification:

    • shopware-app-signature signs the query string of the registration request and uses the app secret shared with your Shopware Account.
    • shopware-shop-signature signs the webhook request body and uses the shop secret created per shop during registration.

    Two rules that matter in practice

    Hash the raw body, before any JSON parsing. Frameworks that re-serialise the request will produce a different byte sequence and therefore a different HMAC.

    Reject requests whose timestamp is too old. An attacker cannot alter the timestamp without invalidating the signature, which makes it a usable defence against replayed requests.

    Shopware recommends using its App PHP SDK or Symfony Bundle rather than implementing verification by hand. Since 6.7.13.0, the signing secret is resolved at delivery time, so deliveries that span a secret rotation are signed with the current secret.

    7. Testing and troubleshooting

    Webhooks fail quietly. Nothing in the storefront indicates that a delivery did not happen, so the first step is always to establish whether Shopware tried at all.

    The webhook event log

    Shopware records delivery attempts in webhook_event_log. If there is no row for the event you expected, the webhook was never queued and the problem is in the manifest or the permissions. If there is a row that never leaves the queued state, the message queue is the problem, not your endpoint.

    A cleanup task removes entries that were successfully delivered or permanently failed, while entries still running or being retried are preserved. Since 6.7.4.0, entries stuck in the queued state are removed after double the configured retention period.

    The usual causes

    • No queue consumer running. Check this first. It accounts for most silent failures.
    • Missing ACL permission for the subscribed event.
    • Endpoint not reachable from the shop server, particularly in local setups without a tunnel.
    • Signature check failing because the body was parsed before hashing, or because the app secret was used instead of the shop secret.
    • Draft versions triggering unexpected events when onlyLiveVersion is not set.

    A minimal endpoint that logs the raw body and returns 200 quickly separates delivery problems from processing problems. Once deliveries arrive reliably, move the processing behind a queue of your own.

    8. Best practices and security

    The design decisions that keep a webhook integration stable are made early, and most of them follow from one property: delivery is asynchronous and may be retried.

    • Verify every request. Check shopware-shop-signature against the raw body before anything else happens.
    • Make handlers idempotent. Use source.eventId, which stays the same across retries, to recognise a request you have already processed.
    • Answer fast, work later. Acknowledge the request and hand the work to your own queue. Long-running processing inside the request risks a timeout and an unnecessary retry.
    • Do not assume ordering. Shopware makes no documented ordering guarantee, and independent retries can reorder deliveries. Re-fetch the current state instead of replaying a sequence.
    • Do not trust the payload as current data. Fetch by primaryKey through the Admin API.
    • Request only the permissions you need. The manifest permissions define what your app can read once it calls back.
    • Reject stale timestamps to limit the window for replayed requests.

    Two behaviours are deliberately absent from this list because Shopware does not document them: the exact HTTP timeout for a delivery, and which status codes are treated as failure. Any integration that depends on specific values there is building on an assumption rather than a specification.

    9. Frequently asked questions

    Do I need a plugin to use webhooks in Shopware 6?

    No. Webhooks are part of the App System and are declared in the app manifest. There is nothing to install from the Shopware Store.

    Why is my webhook not firing?

    In most cases no message queue consumer is running. Shopware queues the delivery and never sends it. Check webhook_event_log to see whether the event was queued at all.

    Why does the payload not contain the full entity?

    Because delivery is asynchronous and a full entity could already be outdated on arrival. Shopware sends the primaryKey and expects you to fetch the current state through the Admin API.

    How often does Shopware retry a failed delivery?

    The webhook documentation does not state a webhook-specific number. Shopware’s general message queue documentation says messages are retried three times before being discarded to the failure transport. Treat that as the expected order of magnitude, not as a guarantee, and use source.eventId for deduplication.

    Can a webhook change what happens in the shop?

    No. A webhook is a notification after the fact. To influence a running request you need a plugin with a PHP event subscriber, which in turn means the shop must be self-hosted.

    Which Shopware versions support this?

    App System webhooks have been part of Shopware core since the 6.3 line. Several details arrived later: the timestamp field and sw-version header in 6.4.1.0, the language headers in 6.4.5.0, and onlyLiveVersion in 6.5.7.0. The current major line is 6.7.

    Latest Posts

    Api First Shopware 2048x1582 1 1536x1187 1

    Why API-First Is a Strategic Advantage for Shopware Teams

    Yotpo Integration Shopware 2048x1582 1

    Yotpo Review & Feedback Tools for E-Commerce Stores

    Klarna Integration Shopware 2048x1582 1

    Klarna & Shopware 6 Integration – Full Documentation Guide

    N8n Integration Shopware 2048x1582 1

    Automating Shopware 6 with n8n – Workflow Integration Guide

    Active Campaign Integration Shopware 2048x1582 1

    ActiveCampaign & Shopware 6 Integration Guide

    Our drive.
    Your growth.

    The agency for e-commerce, software and AI.

    Get free advice
    Company
    • About Us
    • Events
    • Blog
    • Careers
    Events
    • Shopware
    • Shopify
    • Integrations
    • Migration
    Legal
    • Imprint & Legal Information
    • Privacy Policy
    Location
    Bremen Marcusallee 16, 28359 Bremen 0421 438 1919-0 info@solution25.com
    Group 1321315536 1
    Group 1321315537 1

    © 2026 solution25. All rights reserved

    Linkedin Facebook Instagram