answear/inpost-pickup-point-bundle
Symfony bundle for integrating with InPost ShipX pickup points. Install via Composer, then use FindPoints and FindPointsRequestBuilder to search parcel machines by name, type, functions, location (postcode/city/province), partner, availability flags, and pagination.
Installation:
composer require answear/inpost-pickup-point-bundle
The bundle will auto-register in config/bundles.php via Symfony Flex.
First Use Case:
Search for a pickup point by name (e.g., a specific locker code like AK1001):
use Answear\InpostBundle\Request\FindPointsRequestBuilder;
use Answear\InpostBundle\Command\FindPoints;
$request = (new FindPointsRequestBuilder())
->setName('AK1001')
->build();
$response = app(FindPoints::class)->findPoints($request);
Where to Look First:
FindPointsRequestBuilder for filtering logic.FindPoints for execution.// In a Laravel controller or service
public function showCheckout()
{
$postcode = request('postcode');
$points = $this->findPointsByPostcode($postcode);
return view('checkout', compact('points'));
}
protected function findPointsByPostcode(string $postcode)
{
$request = (new FindPointsRequestBuilder())
->setPostCode($postcode)
->setPerPage(10)
->build();
return app(FindPoints::class)->findPoints($request)->getPoints();
}
// Artisan command to cache points for a city
use Illuminate\Console\Command;
use Answear\InpostBundle\Request\FindPointsRequestBuilder;
class CacheInpostPoints extends Command
{
protected $signature = 'inpost:cache {city}';
protected $description = 'Cache Inpost pickup points for a city';
public function handle()
{
$request = (new FindPointsRequestBuilder())
->setCity($this->argument('city'))
->setPerPage(100)
->build();
$points = app(FindPoints::class)->findPoints($request);
cache()->forever("inpost.points.{$this->argument('city')}", $points);
}
}
spatie/laravel-geolocation).$userLocation = User::find(auth()->id())->location;
$nearbyPoints = (new FindPointsRequestBuilder())
->setPostCodes([$userLocation->postcode, ...$userLocation->nearbyPostcodes()])
->setTypes([PointType::LOCKER, PointType::OFFICE])
->build();
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Retry\RetryUntilFailed;
class InpostService
{
public function findPointsWithRetry($request)
{
return RetryUntilFailed::until(
fn() => app(FindPoints::class)->findPoints($request),
3, // Retry 3 times
fn($attempt) => $attempt > 1 ? sleep(1) : null
);
}
}
Laravel-Symfony Bridge:
symfony/http-client or guzzlehttp/guzzle directly if Symfony components are cumbersome.use Symfony\Component\HttpClient\HttpClient;
$client = HttpClient::create();
$response = $client->request('GET', 'https://api.inpost.pl/shipx/v1/points', [
'query' => $request->toArray(),
'headers' => ['Authorization' => 'Bearer ' . config('inpost.api_token')],
]);
Configuration:
config/services.php:
'inpost' => [
'api_token' => env('INPOST_API_TOKEN'),
'base_uri' => env('INPOST_API_BASE_URI', 'https://api.inpost.pl/shipx/v1'),
],
config/packages/answear_inpost.yaml:
answear_inpost:
client:
base_uri: '%env(INPOST_API_BASE_URI)%'
timeout: 30
Testing:
FindPoints command in PHPUnit/Pest:
$mockResponse = new FindPointsResponse([new Point('AK1001', 'Test Locker')]);
$this->app->instance(FindPoints::class, Mockery::mock(FindPoints::class)->shouldReceive('findPoints')->andReturn($mockResponse));
Symfony Dependency:
HttpClient and Serializer. In Laravel, resolve conflicts by:
symfony/http-client as a standalone package.symfony/serializer if Laravel’s native JSON handling suffices.GET Request Body Issue:
FindPointsRequestBuilder uses query parameters only:
$request->setPostCode('00-001')->build(); // Correct (query param)
// Avoid: $request->setBody(['postCode' => '00-001']); // Deprecated
Pagination Quirks:
setPerPage() defaults to 10; Inpost’s API may cap results at 100 per request.setPage() for large datasets:
$points = [];
for ($page = 1; $page <= 5; $page++) {
$request = (new FindPointsRequestBuilder())
->setPostCode('00-001')
->setPage($page)
->setPerPage(100)
->build();
$points = array_merge($points, app(FindPoints::class)->findPoints($request)->getPoints());
}
Timeouts:
answear_inpost:
client:
timeout: 60 # 60 seconds
PHP 8.2+ Enforcement:
php84 Docker images or Laravel Valet/PSA with PHP 8.4+.Italy vs. Poland:
https://api.inpost.pl/shipx/v1/pointshttps://api.inpost.it/shipx/v1/pointsbase_uri in config:
answear_inpost:
client:
base_uri: '%env(INPOST_API_BASE_URI)%' # Set to Italy’s URI if needed
use Psr\Log\LoggerInterface;
class InpostLoggingMiddleware
{
public function __construct(protected LoggerInterface $logger) {}
public function handle($request, Closure $next)
{
$response = $next($request);
$this->logger->
How can I help you explore Laravel packages today?