setono/post-nord-bundle
A Symfony bundle that integrates PostNord shipping services into your application, helping you create shipments, generate labels, and handle tracking through a clean, configurable API wrapper.
Decide which major line you're on before you type composer require. As of the latest release there are two live lines: the stable v1.2.0 and a pre-release v2.0.0-alpha. Composer will not select the alpha by default (it's below minimum-stability: stable), so a bare composer require setono/post-nord-bundle still lands you on ^1.2. Be explicit either way:
composer require setono/post-nord-bundle:^1.2 # stable, default
composer require setono/post-nord-bundle:^2.0@alpha # only if you're deliberately migrating
The alpha pulls in the underlying setono/post-nord-php-sdk transitively — but check which SDK constraint the new composer.json declares, because a bundle major usually accompanies an SDK major.
Read the v2 diff before doing anything else. The v2.0.0-alpha release note is a bare compare link (v1.2.0...v2.0.0-alpha) with no prose, so the diff is the documentation. Highest-value files to inspect, in order:
composer.json — PHP and Symfony constraint bumps, SDK version bumpDependencyInjection/Configuration.php — renamed or removed config keys (the usual reason for a major)Resources/config/services.xml|yaml — changed service ids/aliases, constructor argumentsCHANGELOG.md / UPGRADE*.md if presentRegister Setono\PostNordBundle\SetonoPostNordBundle in config/bundles.php (manually if no Flex recipe).
Write config only after confirming the root alias from Configuration.php (typically setono_post_nord — but re-verify on v2, majors rename aliases). Expect API credentials plus a sandbox/test_mode flag.
# config/packages/setono_post_nord.yaml
setono_post_nord:
api_key: '%env(POSTNORD_API_KEY)%'
customer_number: '%env(POSTNORD_CUSTOMER_NUMBER)%'
test_mode: '%kernel.debug%'
POSTNORD_API_KEY=
POSTNORD_CUSTOMER_NUMBER=
final class ServicePointFinder
{
public function __construct(private readonly PostNordClient $client) {}
public function byPostalCode(string $zip): array
{
// SDK method names live in the vendor SDK's Client class
}
}
If the bundle aliases the SDK client to an interface, autowire that instead. bin/console debug:container PostNord shows what's actually registered — run it on both versions if you're comparing.
Where to look first, in order:
composer.json — constraints and the SDK version you'll actually getResources/config/services.xml (or .yaml) — service ids and aliasesDependencyInjection/Configuration.php — config treeClient class — method names, exceptions, constructor argsShipmentBookingService, LabelGenerator). Controllers and entities never see the SDK type. This is what makes the v1 → v2 jump a one-file change instead of an archaeology project.shipmentId/tracking reference, then generate labels separately. Label endpoints fail independently of booking; a failed PDF shouldn't roll back a real booking.LoggerInterface and Stopwatch; log method, duration, correlation id — never the API key or recipient address. Verify the decorated service id hasn't changed in v2.cache.app with a TTL. Removes most live read traffic.services.yaml with distinct config and alias them by name rather than mutating the bundle's singleton.config/services_test.yaml. If the SDK accepts an injected PSR-18 / HttpClientInterface, use MockHttpClient and assert against recorded request bodies.^1.2 and ^2.0@alpha; the failing assertions are your upgrade checklist.v2.0.0-alpha has no release notes — only a compare link. Do not treat "alpha" as "cosmetic bump." A major on a bundle with zero dependents means the maintainer felt free to rename config keys, drop services, and bump the SDK. Diff Configuration.php by hand; don't assume existing YAML still validates. debug:config setono_post_nord will tell you immediately.^2.0@alpha authorises Composer to pull further alpha/beta/RC releases that can break between deploys. If you go there, pin exactly (2.0.0-alpha1) and expect to re-read the diff on every bump. Otherwise stay on ^1.2 and revisit when 2.0.0 goes stable.composer.json constraints against your Symfony 7 / PHP 8.3 stack before committing, and pin ^x.y. Nobody else has filed the bugs you're about to hit.debug:config setono_post_nord and debug:container --show-private PostNord are faster than any blog post. Trust the source over the README — especially on v2, where the README may still describe v1.test_mode typically flips a base URL. Add a hard guard (if ($kernel->isProd()) around booking) and use separate credentials per environment; a missing flag books real parcels against production.Y-m-d\TH:i:s dates. Validate locally and throw a clear domain exception; PostNord's 4xx messages are terse and won't name the offending field.\Exception. Map Setono\PostNord\... exceptions into your own types and separate "retryable network" from "validation failure" — your Messenger retry policy depends on it. Re-check the exception namespace in v2; it may have moved.composer show setono/post-nord-bundle setono/post-nord-php-sdk so you know which layer (and which major) owns the bug.How can I help you explore Laravel packages today?