Weave Code
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

Vies Laravel Package

dragonbe/vies

PHP Composer package to validate EU VAT numbers via the European Commission VIES SOAP service. Returns country code, VAT number, request date, validity, and (when available) registered company name and address. GDPR-friendly: no data stored by the package.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require dragonbe/vies:^2.3.2
    

    Add the service provider in config/app.php:

    'providers' => [
        // ...
        Dragonbe\Vies\ViesServiceProvider::class,
    ],
    
  2. Basic Usage Inject the Dragonbe\Vies\Facades\Vies facade or service into your controller/service:

    use Dragonbe\Vies\Facades\Vies;
    
    $response = Vies::validate('BE123456789'); // Updated Belgian format support
    
  3. First Use Case Validate a VAT number in a registration form with updated country-specific rules:

    public function validateVat(Request $request)
    {
        $vatNumber = $request->input('vat_number');
        $response = Vies::validate($vatNumber);
    
        if ($response->isValid()) {
            return response()->json(['valid' => true]);
        }
        return response()->json(['valid' => false, 'errors' => $response->getErrors()], 400);
    }
    

Where to Look First

  • Facade: Dragonbe\Vies\Facades\Vies – Primary entry point for all operations.
  • Response Object: Dragonbe\Vies\Response – Contains validation results, errors, and metadata.
  • Configuration: config/vies.php – Adjust timeout, cache settings, or proxy configurations.
  • Country-Specific Rules: Updated format documentation for BE (Belgium) and CY (Cyprus) VAT numbers.

Implementation Patterns

Core Workflows

  1. Validation Workflow

    $response = Vies::validate('CY612345678'); // Updated CY format support (can start with 6)
    if ($response->isValid()) {
        // Proceed with business logic
    } else {
        // Handle errors (e.g., invalid format, non-existent VAT)
    }
    
  2. Batch Validation Useful for bulk processing (e.g., importing supplier data):

    $vatNumbers = ['BE123456789', 'CY612345678', 'FR456789123'];
    $results = Vies::validateBatch($vatNumbers);
    
    foreach ($results as $result) {
        if (!$result->isValid()) {
            Log::error("Invalid VAT: {$result->getVatNumber()}", $result->getErrors());
        }
    }
    
  3. Caching Responses Reduce API calls by caching responses (configured in config/vies.php):

    // Manually cache a response
    Vies::cache('BE123456789', $response, now()->addHours(1));
    
  4. Integration with Laravel Validation Extend Laravel’s validator for seamless form handling:

    use Dragonbe\Vies\Rules\ValidVat;
    
    $request->validate([
        'vat_number' => ['required', new ValidVat],
    ]);
    

Integration Tips

  • Queue Delayed Validations Offload validation to a queue job for long-running processes:

    ValidateVatJob::dispatch($vatNumber)->delay(now()->addMinutes(5));
    
  • Logging Invalid Responses Log failed validations for auditing:

    if (!$response->isValid()) {
        Log::channel('vies_errors')->info($response->toArray());
    }
    
  • Country-Specific Format Validation Use the updated format validation for BE and CY VAT numbers:

    if (!Vies::isValidFormat('BE123')) {
        return response()->json(['error' => 'Invalid Belgian VAT format'], 422);
    }
    
  • Custom Error Handling Override default error messages in your language files (resources/lang/en/vies.php):

    return [
        'invalid_format_be' => 'Belgian VAT numbers must be in the format BE0123456789.',
        'invalid_format_cy' => 'Cypriot VAT numbers must start with 6 or 9 and be in the format CY612345678.',
    ];
    

Gotchas and Tips

Pitfalls

  1. Rate Limiting The VIES API has rate limits (e.g., 1 request per second). Batch requests or cache aggressively to avoid throttling.

    • Fix: Use Vies::validateBatch() and implement exponential backoff for retries.
  2. Country-Specific Formats Updated formats for BE (Belgium) and CY (Cyprus) VAT numbers:

    • Belgium (BE): Must be in the format BE0123456789.
    • Cyprus (CY): Can now start with 6 or 9 (e.g., CY612345678 or CY912345678). Validate locally first:
    if (!Vies::isValidFormat('CY512345678')) { // Will fail (must start with 6 or 9)
        return response()->json(['error' => 'Invalid Cypriot VAT format'], 422);
    }
    
  3. Heartbeat Issues The VIES API's heartbeat mechanism (used to check service availability) is no longer working as expected. Monitor API responses for unexpected failures.

    • Fix: Implement a custom heartbeat check or rely on error handling:
    try {
        $response = Vies::validate('BE123456789');
    } catch (\Dragonbe\Vies\Exceptions\ViesException $e) {
        Log::error("VIES API heartbeat failure: " . $e->getMessage());
    }
    
  4. Caching Stale Data VIES responses can become stale. Set short cache TTLs (e.g., 1 hour) and invalidate on failures:

    Vies::forget('BE123456789'); // Clear cache if validation fails unexpectedly
    

Debugging

  • Enable Debug Mode Add to config/vies.php:

    'debug' => env('APP_DEBUG', false),
    

    This logs raw API responses to storage/logs/vies.log.

  • Mock Responses for Testing Use the Vies::shouldReceive() method in PHPUnit:

    Vies::shouldReceive('validate')
        ->once()
        ->with('BE123456789')
        ->andReturn(new Response(true, [], 'BE123456789'));
    

Extension Points

  1. Custom Response Handlers Extend the Dragonbe\Vies\Response class to add business-specific logic:

    class CustomViesResponse extends \Dragonbe\Vies\Response
    {
        public function isTrustedSupplier()
        {
            return $this->isValid() && in_array($this->getCountryCode(), ['BE', 'CY', 'FR']);
        }
    }
    
  2. Override API Endpoint For testing or custom APIs, bind a custom client in the service provider:

    $this->app->bind('vies.client', function () {
        return new \GuzzleHttp\Client(['base_uri' => 'https://test-vies-api.example.com']);
    });
    
  3. Add Metadata to Responses Extend the validate() method via a decorator pattern:

    $response = Vies::validate('BE123456789');
    $response->setMetadata(['supplier_id' => 123, 'country_rules' => 'BE']);
    
  4. Webhook for Validation Events Listen for validation events (e.g., vies.validated, vies.failed) in EventServiceProvider:

    protected $listen = [
        'Dragonbe\Vies\Events\ValidationSucceeded' => [
            'App\Listeners\LogValidVat',
        ],
    ];
    
  5. Custom Country-Specific Rules Extend the package to handle additional country-specific validations:

    Vies::extendCountryRules(function ($country) {
        if ($country === 'BE') {
            return 'BE\d{10}';
        }
        if ($country === 'CY') {
            return 'CY[69]\d{8}';
        }
        return null;
    });
    
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity