Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

App Bundle Laravel Package

shopware/app-bundle

A Symfony bundle for building Shopware apps, providing the core infrastructure for app manifests, lifecycle events, webhooks, and platform integration. It streamlines app registration, configuration, and communication so developers can add custom features to Shopware 6.

View on GitHub
Deep Wiki
Context7

Getting Started

First decision: this is a Symfony bundle, not a Laravel package. There is no service provider, no config/app.php entry, and no Artisan command. If your Shopware app backend is (or can be) a Symfony application, this bundle is the batteries-included path: it wires the registration handshake, signature verification, webhook routing, payment endpoints, and lifecycle events for you. If your backend must stay in Laravel, do not try to boot this bundle inside Laravel — use the lower-level shopware/app-php-sdk directly and port the handler logic. A common compromise is a small Symfony service that owns the /shopware/app/* routes and calls your Laravel API/queue.

Minimal setup in a Symfony host app:

composer require shopware/app-bundle
// config/bundles.php
return [
    // ...
    Shopware\AppBundle\ShopwareAppBundle::class => ['all' => true],
];
# config/packages/shopware_app.yaml — verify exact keys in
# src/DependencyInjection/Configuration.php, they are the source of truth
shopware_app:
    app_name: '%env(SHOPWARE_APP_NAME)%'
    app_secret: '%env(SHOPWARE_APP_SECRET)%'

Then set SHOPWARE_APP_NAME / SHOPWARE_APP_SECRET, clear the cache, and confirm the bundle's routes are loaded (bin/console debug:router | grep -i shopware).

Where to look first, in order: the README, src/DependencyInjection/Configuration.php (all config keys), src/Resources/config/routes.* (the URLs Shopware will call), and src/Attribute / src/Handler (how handlers are discovered). Ignore the vendor docs until you've read those four.

First use case: get the registration confirmation working, then one webhook. Point a dev store at your backend via the Shopware Admin (App → your app → registration URL), install the app, and watch the confirmation request arrive. Once shopSecret is persisted and a product.written webhook round-trips, the rest is repetition.

Implementation Patterns

Handler-per-topic, discovered by attribute/interface. The idiomatic pattern is one small class per webhook topic or payment method, with the bundle's DI doing the dispatch. Keep them thin: validate, normalize, push to a queue, return. This also maps cleanly to Laravel instincts — a handler is a listener, the bundle's registration is the EventServiceProvider.

Registration handshake. The install flow is: Shopware POSTs the registration with a shopware-app-signature over the query string; you verify it with the app secret, then respond with a JSON payload containing the per-shop shopSecret (plus your app's name/version and secret). Persist shopId, shopUrl, and that returned shopSecret before responding — every subsequent request is verified with the per-shop secret, not the global one. This is the single most common integration bug.

Lifecycle + shop repository. Implement the bundle/SDK shop repository against your own table (or Doctrine entity). installed, updated, and deleted lifecycle handlers should be idempotent: install may be retried, and delete should soft-delete rather than hard-delete so you retain audit history.

Webhook flow for scale. Verify signature on the raw body, then enqueue. Return 200 in milliseconds; Shopware retries on non-2xx and will eventually mark the app as failing. In a Symfony host, that's Messenger with a Doctrine/Redis transport. If Laravel owns the work, the handler should do an authenticated HTTP POST or push to a shared Redis queue.

Payment handlers. Treat these as state machines, not controllers: create/authorize/capture/refund are separate calls, and Shopware will call your return URL in the browser. Keep the redirect URL in config and derive it per shop, not from the request host.

Local development. Expose the backend with a tunnel (ngrok, symfony serve + proxy) and register the tunnel URL in the Shopware Admin. Keep a scratch dev store; app re-registration is cheap and lets you test the handshake repeatedly. For tests, use Symfony's KernelBrowser and generate a valid signature with a fixture secret so you can assert 200/401 paths without a real store.

Laravel coexistence patterns. Two workable shapes: (1) Symfony app at app.example.com/shopware/* behind the same load balancer as the Laravel app, sharing a database or calling internal APIs; (2) Laravel-only, using shopware/app-php-sdk's handler interfaces and reimplementing the ~5 routes yourself. The second is more code but avoids two frameworks in one deployment.

Gotchas and Tips

  • Framework mismatch is the real cost. Every Laravel convenience — facades, Eloquent, queues, config() — is absent. Budget for Doctrine or a PDO layer, Symfony Messenger, and the Symfony DI config format. If the team is Laravel-only, the SDK route is usually cheaper than learning the bundle's conventions.
  • Sign the raw bytes. Verify shopware-app-signature against the untouched request body (webhooks) or the URL-decoded query string (registration) before any middleware, JSON decoding, or body parsing rewrites it. HMAC over a re-encoded array will fail intermittently.
  • Per-shop secrets, not the global secret. As above: the global app secret only validates first contact. Store the returned shopSecret per shop and use it for all later signatures.
  • Exclude the app routes from the security firewall and CSRF. These are stateless, server-to-server calls with no session. A firewall redirect to a login page returns a 302, which Shopware reads as a failure.
  • Fast 200s and idempotency. Webhooks can be delivered more than once. Key your processing on shopId + topic + payload hash or an event id, and make handlers retry-safe.
  • Route prefix and trailing slashes. Shopware stores the exact registration URL. Changing the prefix later means re-registering every shop. Pick /shopware/app (or similar) on day one and version it if you must change.
  • Config and cache. In production, env vars are resolved at container compile time. bin/console cache:clear after config changes; quote env values that contain special characters in YAML.
  • Small ecosystem. ~16 stars and no dependents means no Stack Overflow safety net. Pin the version in composer.json, read src/ when behavior surprises you, and check the release tags — the metadata's last-release date is ahead of the current date, so confirm what's actually installable before planning around it.
  • Return correct status codes deliberately. 401 on bad signature, 400 on malformed payload, 200 on accepted-and-queued. Repeated 5xx responses cause Shopware to disable the app.
  • Extension points to reach for: decorate a handler service to add cross-cutting concerns (logging, metrics), an event subscriber on the bundle's dispatched events, and a compiler pass if you need to tag handlers dynamically. Overriding routes is possible but fragile — prefer decorating over replacing.
  • Test with real payloads. Capture a few webhook bodies and signatures from a dev store into fixtures. Synthetic payloads miss fields like shopId, source, and the nested payload envelope that handlers actually rely on.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect