spatie/bpost-address-webservice
PHP wrapper for bpost’s Address Webservice. Create Address objects and validate Belgian addresses, receiving normalized fields plus warnings/errors/issue lists you can inspect and act on. Useful for checkout forms and address cleanup.
Installation:
composer require spatie/bpost-address-webservice
Publish the config (if needed) with:
php artisan vendor:publish --provider="Spatie\BpostAddressWebservice\BpostAddressWebserviceServiceProvider"
First Use Case: Validate a Belgian address in a form submission or API endpoint:
use Spatie\BpostAddressWebservice\Address;
use Spatie\BpostAddressWebservice\AddressValidator;
$address = Address::create([
'streetName' => 'Samberstraat',
'streetNumber' => '69',
'postalCode' => '2060',
'municipalityName' => 'Antwerpen',
'country' => 'BELGIE',
]);
$validator = AddressValidator::create();
$validatedAddress = $validator->validate($address);
if ($validatedAddress->hasErrors()) {
// Handle errors (e.g., redirect with flash message or return API error)
}
Where to Look First:
config/bpost-address-webservice.php (API key, endpoint, timeout).Spatie\BpostAddressWebservice\Address (required fields, validation rules).Spatie\BpostAddressWebservice\AddressValidator (methods like validate(), hasErrors()).Form Validation (Laravel Blade):
// In a controller
public function store(Request $request) {
$address = Address::create($request->validated());
$validated = AddressValidator::create()->validate($address);
if ($validated->hasErrors()) {
return back()->withErrors($validated->errors());
}
// Proceed with saving...
}
API Endpoint:
public function validateAddress(Request $request) {
$address = Address::create($request->all());
$validated = AddressValidator::create()->validate($address);
return response()->json([
'valid' => !$validated->hasErrors(),
'issues' => $validated->issues(),
]);
}
Bulk Validation:
$addresses = collect([...]); // Array of Address models
$validated = $addresses->map(fn ($addr) => AddressValidator::create()->validate($addr));
Autocomplete Integration:
Use the AddressSuggestionFinder to fetch suggestions for street names or municipalities:
$finder = AddressSuggestionFinder::create();
$suggestions = $finder->findSuggestions('Antw');
use Spatie\BpostAddressWebservice\Rules\ValidBpostAddress;
$request->validate([
'address' => ['required', new ValidBpostAddress],
]);
Cache::remember("bpost_{$postalCode}", now()->addHours(1), fn() => $validator->validate($address));
ValidateBpostAddress::dispatch($address)->onQueue('bpost');
AddressValidator in tests:
$mockValidator = Mockery::mock(AddressValidator::class);
$mockValidator->shouldReceive('validate')->andReturn($validatedAddress);
API Key Requirements:
.env or config/bpost-address-webservice.php).Spatie\BpostAddressWebservice\Exceptions\MissingApiKey..env:
BPOST_ADDRESS_WEBSERVICE_API_KEY=your_key_here
Rate Limiting:
try {
$validator->validate($address);
} catch (RateLimitExceededException $e) {
sleep(10); // Wait and retry
retry();
}
Field Requirements:
country must be "BELGIE") will fail silently or return generic errors.if (!$address->isValid()) {
throw new \InvalidArgumentException('Address is missing required fields.');
}
Municipality Name Sensitivity:
"Antwerpen" ≠ "ANTWERPEN").$address->municipalityName = Str::upper($request->municipalityName);
Box Number Handling:
boxNumber field is optional but must be omitted if not applicable (e.g., no box for a street address).null if unused:
$address->boxNumber = $request->boxNumber ?? null;
Enable Debug Mode:
Set debug to true in config to log raw API responses:
'debug' => env('BPOST_DEBUG', false),
Check logs in storage/logs/laravel.log.
HTTP Client Errors:
try-catch to handle:
ConnectionException: Network issues.ServerException: Bpost API downtime.DecodingException: Invalid response format.try {
$validated = $validator->validate($address);
} catch (\Exception $e) {
report($e); // Log to Sentry/Laravel
throw new \RuntimeException('Failed to validate address: ' . $e->getMessage());
}
Testing Locally:
AddressValidator’s setClient() method to mock HTTP calls in tests:
$validator->setClient($mockClient);
Custom Validation Logic:
Extend the Address model to add business rules:
class CustomAddress extends Address {
public function rules() {
return array_merge(parent::rules(), [
'streetName' => ['required', 'max:100'],
]);
}
}
Webhook Integration:
Listen for Bpost API webhooks (e.g., address changes) by extending the WebhookHandler:
class CustomWebhookHandler extends WebhookHandler {
public function handle(array $payload) {
// Custom logic for payloads like 'address_updated'
}
}
Fallback for Offline Use: Implement a fallback validator for when the Bpost API is unavailable:
class FallbackValidator {
public function validate(Address $address) {
// Simple regex checks or local DB lookup
}
}
Localization: Override error/warning messages in language files:
// resources/lang/en/bpost.php
return [
'errors' => [
'invalid_postal_code' => 'The postal code :code is invalid for Belgium.',
],
];
How can I help you explore Laravel packages today?