ibericode/vat-bundle
Symfony bundle wrapping the ibericode/vat library to validate EU VAT numbers against the official VIES service. Check VAT IDs, retrieve registered company details, and add reliable, framework-friendly VAT validation to any Symfony application. Supports all EU member states.
Architecture fit. The single most important finding: ibericode/vat-bundle is a Symfony bundle, not a Laravel package. It registers through Symfony's Kernel::registerBundles() and the DependencyInjection\Extension / Configuration tree mechanism, neither of which exists in Laravel. Its practical value in a Laravel estate is therefore close to zero as packaged. The value sits in its underlying library, ibericode/vat, which is framework-agnostic PHP and installs and runs cleanly under Laravel. A TPM should frame the decision as "adopt the library, ignore the bundle" unless a Symfony service is already in scope.
Integration feasibility. High, once scoped to the library. ibericode/vat exposes two distinct capabilities that should be evaluated separately: (1) VAT number validation, which performs a remote check against VIES plus format rules per member state, and (2) VAT rate lookup, which is largely local data shipped with the library and refreshed on releases. Both are small, synchronous, low-ceremony APIs. Integration in Laravel is a thin wrapper: a service provider, a config file, a singleton binding behind an interface, and a cache layer. This is roughly a day of engineering, not a project.
Technical risk.
Key questions. Do we need validation, rate lookup, or both? Is B2B reverse charge in scope, and who signs off on the tax logic? What is our tolerance for VIES downtime at checkout? Do we have a regulatory obligation to store VIES consultation evidence (consultation number, timestamp, request/response) for reverse-charge invoices? Is any Symfony service in the estate that would justify the bundle itself? What are our PHP and Laravel version floors?
Stack fit. Consume ibericode/vat directly via Composer. Bind it in a dedicated service provider behind an application-owned interface (e.g. VatValidator, VatRateProvider) so the vendor library is never referenced from controllers or models. Put thresholds, cache TTLs, timeouts, and a feature flag for offline mode in config/vat.php. Skip the bundle entirely — do not attempt to shim Symfony's DI extension system into Laravel.
Migration path. If a Symfony service already uses the bundle, the correct seam is the shared underlying library and the business rules it encodes, not the bundle. Both stacks consume the same vendor package, so validation semantics stay consistent across services. For greenfield Laravel work, there is nothing to migrate — we are writing a wrapper around a library, not porting a bundle.
Compatibility. Verify the library's PHP constraint against our floor and confirm it does not require Symfony HttpKernel or EventDispatcher at runtime (a PSR HTTP client dependency is fine). Laravel already pins several symfony/* components; check for constraint collisions on symfony/console, symfony/http-foundation, and symfony/process before merging. Confirm the VIES transport (SOAP vs REST) against our outbound network and proxy rules.
Sequencing.
Maintenance. Two layers to own: the vendor library (pin with a caret constraint, review monthly — releases carry rate data and VIES API changes) and our wrapper. The bundle adds a third layer we would not use, so excluding it reduces surface. Rate data changes are statutory, not cosmetic; a stale release is a compliance issue, so a calendar reminder tied to known EU rate-change dates is warranted.
Support. Failures surface at checkout, which makes them visible and expensive. Support needs a runbook covering: VIES unreachable, member-state-specific outage, format-valid but unregistered number, and the manual override path. Decide in advance whether a failed validation blocks the order or routes it to a pending-review queue.
Scaling. Rate lookup is effectively free — local data, in-process. Validation is the only scaling concern and it is entirely an external-call problem: enforce a cache with a TTL aligned to EU re-validation guidance (typically on the order of a day, not per request), never call VIES per page render, and set aggressive timeouts with a circuit breaker.
Failure modes. VIES timeout or total unavailability; individual member-state service down (VIES returns a distinct "unavailable" status that must not be conflated with "invalid"); stale rate data after a statutory change; a cached "valid" result retained after a business deregisters; silent fallback that masks genuine validation failures and creates reverse-charge tax exposure; and misapplication of reverse charge by well-meaning engineers. The last two are the ones with financial consequences and deserve explicit test coverage.
Ramp-up. Low on the engineering side — a mid-level Laravel developer can own this in a sprint. The real ramp-up is domain knowledge: reverse charge, place of supply, and evidence retention. Budget a review session with finance/tax before the first production integration, not after. Given the low opportunity score and thin community footprint, treat this as a build-a-thin-wrapper decision rather than a package adoption decision.
How can I help you explore Laravel packages today?