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

Vat Laravel Package

mibo/vat

mibo/vat is a Laravel/PHP package for VAT handling, offering a simple API to manage VAT rates and calculate net, tax, and gross amounts. It helps keep VAT logic clean, configurable, and easy to integrate into your applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Install via Composer and let Laravel's package discovery register the service provider:

composer require mibo/vat
php artisan vendor:publish --tag=vat-config   # check README; tag name may differ

First place to look is the published config/vat.php and the package's README.md — with a low-adoption package (0 stars, 0 dependents), treat the source as the source of truth. Confirm the exact entry point before wiring it in: check src/ for a facade, a service class, or a Vat model/trait, and note whether calls hit VIES live or resolve from a cached table.

The first use case to build against is the classic EU B2B flow: a customer enters a VAT ID at checkout, you validate it, store the result, and if valid on a cross-border B2B sale, apply the reverse-charge rule (0% VAT, invoice marked "reverse charge"). Get that end-to-end before touching rate lookup for B2C.

// Verify the actual namespace/method names against src/ before assuming these
$result = Vat::validate('DE123456789');

if ($result->isValid()) {
    $order->vat_id       = 'DE123456789';
    $order->vat_verified = now();
    $order->reverse_charge = $customerCountry !== $sellerCountry;
}

Implementation Patterns

Validate on write, not on read. VAT ID status changes; VIES can flake out. Store vat_id, vat_valid, vat_checked_at, and the raw response (or a hash of it) on the customer/order. Re-check on significant events (account creation, first order, an explicit "revalidate" admin action) rather than every page load.

Centralise validation in a single service. Wrap the package in a small VatValidator app service so you can swap implementations later and inject caching, logging, and retry logic in one place instead of scattering it.

class VatValidator
{
    public function check(string $vatId, ?string $countryCode = null): VatResult
    {
        return Cache::remember("vat:{$vatId}", now()->addHours(24), function () use ($vatId, $countryCode) {
            $result = Vat::validate($vatId, $countryCode);
            Log::info('vat.validate', ['vat_id' => $vatId, 'valid' => $result->isValid()]);
            return $result;
        });
    }
}

Derive country from the ID prefix, but cross-check. VAT IDs carry a two-letter country prefix (DE, FR, IT, NL, AT, etc.); validate that prefix against the customer's billing country and reject mismatches — this catches fat-fingered IDs and is a cheap first gate before hitting VIES.

Reverse charge needs both conditions. A valid VAT ID alone does not mean reverse charge applies. You need: B2B sale, valid VAT ID, and cross-border (seller country ≠ customer country). Keep those three checks explicit in your order pipeline and test each branch.

Cache aggressively and deliberately. VIES is a shared external SOAP service; hammering it per page view is how you get rate-limited. Cache per VAT ID for 24h–7d depending on risk tolerance, and never cache a negative result as long as a positive one.

Rate lookup for invoicing. If the package exposes VAT rates per country, resolve them at invoice-generation time and snapshot the rate plus the resolved country on the invoice line — never re-derive from live data when rendering a historical invoice.

Events and async. If VIES latency is a problem at checkout, validate synchronously only for the "is this ID well-formed and does it pass a best-effort check" step, and queue a full VIES confirmation. Send a follow-up email and flag the order if it later fails.

Gotchas and Tips

  • VIES is unreliable. Timeouts, SOAP faults, and maintenance windows are routine. Distinguish "confirmed invalid" from "could not check" in your result handling — treating a timeout as invalid will reject paying customers, which is worse than the fraud you're guarding against. Fail open (accept, flag for manual review) rather than closed at checkout.
  • Validation ≠ legitimacy. A VAT ID can be valid and still belong to a dormant or fraudulent company. Don't build your entire fraud posture on this; use it as one signal and log it.
  • Watch the caching key. VAT IDs are case-insensitive and sometimes entered with spaces or dots. Normalise (uppercase, strip whitespace) before using as a cache key, or you'll get cache misses and duplicate VIES calls.
  • Testing. Never hit VIES from CI. Bind a fake client into the container in tests, or use the package's config to point at a mock endpoint if it offers one. Confirm what the package does in testing/local environments — many packages ship a null client or a fixture; verify it.
  • Config quirks. Check the default timeout and whether the package retries. Defaults often favour correctness over latency; set a short timeout (2–5s) for synchronous checkout calls and move retries to the queue.
  • Extension points. Look for a bound interface (e.g. a Validator or Client contract) in the service provider; if one exists, bind your own implementation via app()->bind() to add caching/retry/logging without forking. If not, wrap the facade as shown above — that's your stable seam.
  • Audit trail. Persist the raw validation response alongside the order. Tax authorities and enterprise customers ask for evidence of VAT ID checks during audits, and "we called VIES once at checkout" is not evidence.
  • Version pinning. With 0 stars and 0 dependents, the maintainer is the only safety net. Pin an exact version in composer.json, read the changelog before upgrading, and keep the wrapper thin so replacing the package is a day's work, not a rewrite.
  • Debugging. Log the request (VAT ID, country) and the raw response at info level. When a customer claims their ID is valid but your system rejected it, you need to see the exact VIES payload, not just the boolean.
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