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

Inpost Pickup Point Bundle Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require answear/inpost-pickup-point-bundle
    

    The bundle will auto-register in config/bundles.php via Symfony Flex.

  2. 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);
    
  3. Where to Look First:


Implementation Patterns

Core Workflows

1. Checkout Integration (Real-Time Search)

  • Pattern: Use during address selection or order confirmation.
  • Example:
    // 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();
    }
    
  • UI: Render a dropdown or modal with results, including:
    • Distance from user’s location (calculate via Haversine formula).
    • Point type (locker/office) and opening hours.

2. Bulk Data Fetch (Admin/Analytics)

  • Pattern: Pre-fetch and cache pickup points for regions.
  • Example:
    // 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);
        }
    }
    

3. Geographic Filtering

  • Pattern: Combine with Laravel’s geolocation (e.g., spatie/laravel-geolocation).
  • Example:
    $userLocation = User::find(auth()->id())->location;
    $nearbyPoints = (new FindPointsRequestBuilder())
        ->setPostCodes([$userLocation->postcode, ...$userLocation->nearbyPostcodes()])
        ->setTypes([PointType::LOCKER, PointType::OFFICE])
        ->build();
    

4. Error Handling & Retries

  • Pattern: Wrap API calls in a service with retry logic.
  • Example:
    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
            );
        }
    }
    

Integration Tips

  • Laravel-Symfony Bridge:

    • Use symfony/http-client or guzzlehttp/guzzle directly if Symfony components are cumbersome.
    • Example:
      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:

    • Add to config/services.php:
      'inpost' => [
          'api_token' => env('INPOST_API_TOKEN'),
          'base_uri' => env('INPOST_API_BASE_URI', 'https://api.inpost.pl/shipx/v1'),
      ],
      
    • Override the bundle’s client in config/packages/answear_inpost.yaml:
      answear_inpost:
          client:
              base_uri: '%env(INPOST_API_BASE_URI)%'
              timeout: 30
      
  • Testing:

    • Mock the 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));
      

Gotchas and Tips

Pitfalls

  1. Symfony Dependency:

    • The bundle uses Symfony’s HttpClient and Serializer. In Laravel, resolve conflicts by:
      • Using symfony/http-client as a standalone package.
      • Avoiding symfony/serializer if Laravel’s native JSON handling suffices.
  2. GET Request Body Issue:

    • Gotcha: Release 4.1.0 removed request bodies from GET requests, which may break custom integrations.
    • Fix: Ensure your FindPointsRequestBuilder uses query parameters only:
      $request->setPostCode('00-001')->build(); // Correct (query param)
      // Avoid: $request->setBody(['postCode' => '00-001']); // Deprecated
      
  3. Pagination Quirks:

    • Gotcha: setPerPage() defaults to 10; Inpost’s API may cap results at 100 per request.
    • Tip: Use 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());
      }
      
  4. Timeouts:

    • Gotcha: Default timeout is 10 seconds (set in 3.0.2). Slow responses may fail.
    • Fix: Increase timeout in config:
      answear_inpost:
          client:
              timeout: 60 # 60 seconds
      
  5. PHP 8.2+ Enforcement:

    • Gotcha: The bundle drops support for PHP < 8.2 (since 3.1.0).
    • Tip: Use php84 Docker images or Laravel Valet/PSA with PHP 8.4+.
  6. Italy vs. Poland:

    • Gotcha: The bundle supports both, but endpoints differ:
      • Poland: https://api.inpost.pl/shipx/v1/points
      • Italy: https://api.inpost.it/shipx/v1/points
    • Fix: Override base_uri in config:
      answear_inpost:
          client:
              base_uri: '%env(INPOST_API_BASE_URI)%' # Set to Italy’s URI if needed
      

Debugging Tips

  1. Enable API Logging:
    • Add middleware to log requests/responses:
      use Psr\Log\LoggerInterface;
      
      class InpostLoggingMiddleware
      {
          public function __construct(protected LoggerInterface $logger) {}
      
          public function handle($request, Closure $next)
          {
              $response = $next($request);
              $this->logger->
      
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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
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
christhompsontldr/laravel-inky