answear/mwl-pickup-point-bundle
Installation:
composer require answear/mwl-pickup-point-bundle
The bundle auto-registers in config/bundles.php via Symfony Flex.
Configuration:
Add your MWL credentials to config/packages/answear_mwl.yaml:
answear_mwl:
partnerKey: 'your-partner-key'
secretKey: 'your-secret-key'
First Use Case: Fetch pickup points for a specific carrier/country (e.g., Meest in Ukraine):
use Answear\MwlBundle\Command\GetPickupPointsByCarriersAndCountryCodes;
use Answear\MwlBundle\Request\GetPickupPointsByCarriersAndCountryCodesRequest;
use Answear\MwlBundle\Request\Struct\CarrierAndCountryCode;
use Answear\MwlBundle\Enum\{CarrierEnum, CountryCodeEnum};
$request = new GetPickupPointsByCarriersAndCountryCodesRequest([
new CarrierAndCountryCode(CarrierEnum::Meest, CountryCodeEnum::Ukraine),
]);
$response = app()->get(GetPickupPointsByCarriersAndCountryCodes::class)
->getPickupPointsByCarriersAndCountryCodesRequest($request);
Key Classes:
GetPickupPoints, GetPickupPointsByCarriersAndCountryCodes, GetCitiesCarrierEnum, CountryCodeEnum (for filtering)GetPickupPointsRequest).Fetching Pickup Points:
GetPickupPoints for all points (no filters).
$response = app()->get(GetPickupPoints::class)
->getPickupPoints(new GetPickupPointsRequest());
GetPickupPointsByCarriersAndCountryCodes for targeted results (e.g., Meest in Poland).
$response = app()->get(GetPickupPointsByCarriersAndCountryCodes::class)
->getPickupPointsByCarriersAndCountryCodesRequest($filteredRequest);
City Lookup: Fetch cities by country (e.g., for dropdowns in UIs):
$cities = app()->get(GetCities::class)
->getCities(new GetCitiesRequest());
Response Handling:
$pickupPoints = $response->getPickupPoints();
foreach ($pickupPoints as $point) {
echo $point->getName(); // e.g., "Nova Poshta #12345"
}
getResponse() (added in v2.2.0) for raw API responses if needed.Dependency Injection: Bind commands to services for reusability:
// services.yaml
services:
Answear\MwlBundle\Command\GetPickupPointsByCarriersAndCountryCodes:
tags: ['container.service_subscriber']
Then inject via constructor:
public function __construct(
private GetPickupPointsByCarriersAndCountryCodes $command
) {}
Caching: Cache responses (e.g., cities/pickup points) to reduce API calls:
$cacheKey = 'mwl_pickup_points_meest_ua';
$pickupPoints = Cache::remember($cacheKey, 3600, fn() => $command->execute($request));
Error Handling: Wrap calls in try-catch for API errors:
try {
$response = $command->execute($request);
} catch (\Answear\MwlBundle\Exception\MwlException $e) {
// Log or retry (e.g., $e->getCode() for HTTP status)
throw new \RuntimeException('MWL API failed', 0, $e);
}
Testing:
Mock the ConfigProvider to isolate tests:
$this->mock(ConfigProvider::class)
->shouldReceive('getPartnerKey')
->andReturn('test-key');
Authentication:
partnerKey/secretKey are invalid, the API returns 401 Unauthorized. Validate config early:
if (empty(config('answear_mwl.partnerKey'))) {
throw new \RuntimeException('MWL keys not configured');
}
Data Structure:
// ❌ Wrong (throws UndefinedIndexException)
$response['pickupPoints'][0]['name'];
Use:
// ✅ Correct
$response->getPickupPoints()[0]->getName();
Enum Usage:
CarrierEnum::MEEST (uppercase) vs. CarrierEnum::Meest (PascalCase). Stick to the latter.Deprecations:
getCitiesByCountry) may be deprecated. Prefer new structured requests.Raw API Responses:
Use getResponse() (v2.2.0+) to inspect raw data:
$rawResponse = $response->getResponse();
dd($rawResponse->getBody()->getContents());
Logging: Enable Guzzle logging to debug HTTP calls:
$client = new \GuzzleHttp\Client([
'handler' => \GuzzleHttp\HandlerStack::create([
new \GuzzleHttp\Middleware::tap(function ($request, $options) {
\Monolog\Logger::getInstance()->info('MWL Request:', [
'url' => (string) $request->getUri(),
'method' => $request->getMethod(),
]);
}),
]),
]);
Bind the custom client to the bundle’s HttpClient service.
Common Errors:
400 Bad Request: Invalid CarrierAndCountryCode combinations (e.g., Meest + Germany).500 Server Error: Contact MWL support; cache responses temporarily.Custom Requests:
Extend the Request classes to add fields (e.g., radius search):
class CustomPickupPointsRequest extends GetPickupPointsRequest {
public function __construct(
public ?int $radius = null,
public ?string $city = null
) {}
}
Update the command to handle the new request.
Response Transformers: Decorate responses for your domain:
$transformed = $response->getPickupPoints()->map(fn($point) => new PickupPointDto(
$point->getId(),
$point->getName(),
// ...
));
Event Listeners: Trigger events on successful/failed API calls:
// src/EventListener/MwlListener.php
public function onMwlResponse(MwlResponseEvent $event) {
if ($event->isSuccess()) {
Cache::put('mwl_last_sync', now());
}
}
Register the listener in services.yaml.
Testing Helpers:
Create a test double for ConfigProvider:
// tests/Unit/Mock/MwlConfigProvider.php
class MockConfigProvider extends ConfigProvider {
public function getPartnerKey() { return 'test-key'; }
public function getSecretKey() { return 'test-secret'; }
}
Override the service in tests:
$this->app->bind(ConfigProvider::class, MockConfigProvider::class);
How can I help you explore Laravel packages today?