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

Shopware Sdk Bundle Laravel Package

it-bens/shopware-sdk-bundle

Symfony bundle that integrates the Shopware SDK into your application, wiring configuration and dependency injection so you can use Shopware Admin and Storefront API clients through convenient Symfony services.

View on GitHub
Deep Wiki
Context7

Getting Started

1. Install and register

composer require it-bens/shopware-sdk-bundle:^0.7

0.x versioning means minor bumps can break you — pin the exact version you tested (0.7.0) rather than a floating constraint, and commit composer.lock.

There is likely no Symfony Flex recipe (0 dependents, 2 stars), so verify and register manually in config/bundles.php:

ItBens\ShopwareSdkBundle\ShopwareSdkBundle::class => ['all' => true],

2. Configure credentials

Never inline secrets; use env/.env.local or Symfony Secrets (bin/console secrets:set SHOPWARE_ADMIN_CLIENT_ID).

# config/packages/it_bens_shopware_sdk.yaml
it_bens_shopware_sdk:
    shop_url: '%env(SHOPWARE_SHOP_URL)%'
    cache: 'shopware.cache'   # v0.7.0+: a service id, or null to disable
    # admin + store credentials — dump the exact keys:
    # bin/console config:dump-reference it_bens_shopware_sdk

cache changed shape in v0.7.0: it is no longer true/false. Point it at a cache pool service id (e.g. a dedicated cache.app.shopware pool) or null to turn caching off. A leftover cache: true will fail config validation.

3. See what was registered

bin/console debug:container it_bens --show-private
bin/console debug:config it_bens_shopware_sdk

The bundle's job is broader than it looks: it registers/autowires the SDK's AdminApi and StoreApi services with your credentials, wires the configured cache, and collects entity-definition collection populators (see Implementation Patterns). Everything else is the SDK.

4. First use case

A one-off console command is the safest first integration: it exercises auth, config, and HTTP without touching request/response cycles.

#[AsCommand(name: 'app:shopware:smoke-test')]
final class SmokeTestCommand extends Command
{
    public function __construct(private readonly AdminApi $adminApi) { parent::__construct(); }

    protected function execute(InputInterface $in, OutputInterface $out): int
    {
        // Example call surface — confirm against the SDK README
        $result = $this->adminApi->get('/api/_info/version');
        $out->writeln(json_encode($result));
        return Command::SUCCESS;
    }
}

If that returns a version, the bundle is wired correctly. If it throws a 401, your admin client id/secret are wrong; a 404 usually means shop_url is wrong (subdirectory/trailing slash).

Implementation Patterns

Keep the SDK behind your own interface. Given the adoption footprint, treat this bundle as an implementation detail. Wrap it:

interface ProductFetcherInterface { public function fetch(string $id): ProductDto; }

final class ShopwareProductFetcher implements ProductFetcherInterface
{
    public function __construct(private readonly AdminApi $adminApi) {}

    public function fetch(string $id): ProductDto
    {
        $raw = $this->adminApi->get('/api/product/' . $id);
        return ProductDto::fromArray($raw); // map to your own DTOs, not SDK types
    }
}

Controllers, handlers, and Twig never see SDK classes. Swapping the SDK (or upgrading it) becomes a one-file change.

Split Admin vs Store. The bundle exposes two API services with different credentials and semantics:

  • StoreApi → storefront-facing reads (products, categories, checkout), uses the Store API access key, respects sales-channel scoping.
  • AdminApi → full CRUD, uses OAuth client credentials, should only be reachable from back-office/console/worker code.

Put admin calls behind an interface bound only where needed, so storefront requests can't accidentally use admin credentials.

Entity definition collection populators (v0.7.0). The bundle collects "entity definition collection populators" — classes that contribute entity definitions to the SDK — and v0.7.0 changed how they're discovered. It used to scan the DI container; it now relies on the AsEntityDefinitionCollectionPopulator attribute/interface:

#[AsEntityDefinitionCollectionPopulator]
final class MyEntityDefinitionCollectionPopulator implements EntityDefinitionCollectionPopulatorInterface
{
    // ...
}

Practical consequences: keep autoconfigure: true on the service definitions in the directory where these live, or tag them explicitly. Anything that previously "just worked" via container scanning while sitting in a non-autoconfigured or manually-registered service block will silently stop being collected. Verify with debug:container --tag=<tag from the attribute> after upgrading.

Dedicated cache pool. Since v0.7.0 the cache target is a service id, define an explicit pool so token/entity caches don't share eviction pressure with your app cache:

# config/packages/cache.yaml
framework:
    cache:
        pools:
            shopware.cache:
                adapter: cache.adapter.redis
                default_lifetime: 600

Go async for anything bulk. Shopware Admin API is rate-limited and slow under load. For imports, syncs, and webhooks use Messenger:

#[AsMessageHandler]
final class SyncOrderHandler
{
    public function __construct(private readonly AdminApi $adminApi) {}

    public function __invoke(SyncOrder $message): void
    {
        $this->adminApi->post('/api/order', $message->payload);
    }
}

Configure a retry strategy on the transport (retry_strategy: max_retries: 3, delay: 1000, multiplier: 2). Shopware's admin tokens expire (~10 min default); in long-running workers, expect occasional 401s and retry rather than assuming a token lives forever.

Config as a service layer. Bind shop-specific parameters (sales channel id, default currency, etc.) as container parameters and inject them into small "Shopware client" services per concern (OrderClient, ProductClient) rather than passing raw endpoint paths around the codebase.

Testing. Mock your own interfaces in unit tests. For light integration tests, the SDK accepts custom HTTP clients in most versions — check the bundle's service definition; if the HTTP client is a registered service you can decorate or replace it in config/services_test.yaml with MockHttpClient to avoid hitting a real shop. Point cache: null in config/packages/test/ so tests don't read stale tokens from a shared pool.

Multi-shop. The bundle config is global (one shop). For multi-tenant setups, build your own factory that instantiates SDK API clients directly per shop and register them as keyed services — don't try to fight the bundle's single-instance autowiring.

Gotchas and Tips

  • v0.7.0 breaking change: cache config. true/false are gone. Use a cache pool service id or null. Grep your configs (including config/packages/*/) before bumping — a cache: true left in a per-env file is a hard config failure at container compile, not a runtime warning.
  • v0.7.0 breaking change: no deep merge of credentials. Credential configuration is no longer deep-merged across environment configs, which previously caused surprising bleed-through. The intent is that each environment declares a complete credential set. In practice: don't rely on config/packages/it_bens_shopware_sdk.yaml supplying client_id while config/packages/prod/... only overrides client_secret. Override whole credential blocks, or — better — keep every value as an %env()% reference and vary only .env files per environment.
  • v0.7.0 breaking change: populator discovery. Container-scanning discovery is replaced by the AsEntityDefinitionCollectionPopulator interface/attribute. If your populators live in a bundle or a services.yaml entry with autoconfigure: false, they will no longer be collected — the failure is silent (no error, just missing definitions). Re-check after upgrading and add the tag manually if needed.
  • Low adoption risk. 2 stars, 0 dependents, single maintainer. Pin the exact version in composer.json, commit composer.lock, and read the changelog before bumps. Three behaviour changes in one minor release is the pattern to plan for: budget time for a fork if it stalls.
  • No Flex recipe. You'll likely need to edit config/bundles.php and create the config file by hand. config:dump-reference is your source of truth for key names, not blog posts.
  • Two credential sets. Store API access key ≠ Admin API client id/secret. Mixing them up produces a 401 that looks like a config error but is really a credential-scope error.
  • shop_url format is the #1 cause of failures. Include the scheme, exclude the trailing slash, and include any subdirectory (https://shop.example.com/shopware). Most 404s are here.
  • TLS in dev. Self-signed certs on a staging shop will surface as opaque SDK exceptions — configure your HTTP client's verify_peer/cacert rather than disabling TLS globally.
  • cache:clear costs you a re-auth. Clearing the pool forces a fresh OAuth token and a fresh entity-definition collection. Harmless, but expect a latency spike after deploy; don't be surprised by a burst of token requests.
  • Error visibility. SDK exceptions often wrap an HTTP response but don't always expose the body. Catch the SDK's exception, log $e->getPrevious() and any response body, and assert status codes in tests — otherwise Shopware's verbose error payloads (which contain the actual field validation message) are lost.
  • Long-running processes. Tokens expire mid-worker. Wrap calls in a small retry-on-401 helper, or recreate the API service periodically in messenger:consume loops.
  • Rate limits. Shopware returns 429s under load. Add exponential backoff at the transport layer, and keep admin bulk operations on separate Messenger queues from user-facing jobs.
  • Extension points. debug:container --show-private --tag=... reveals the SDK service ids and the populator tag. You can decorate AdminApi/StoreApi with a logging decorator (great for auditing admin writes) or use a compiler pass to swap the HTTP client. Prefer decoration over editing the bundle's config.
  • Version matrix. The bundle tracks a specific shopware/api-client lineage, and 0.x releases are not shy about changing config shape. Confirm the SDK's supported Shopware 6.x range against your target before committing — mismatched minor versions on endpoints like /api/product cause subtle 400s.
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.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource