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

Paypalhttp Laravel Package

paypal/paypalhttp

Deprecated PayPalHttp SDK: a lightweight generic PHP HTTP client for PayPal-style REST APIs. Provides Environment base URL handling, request/response objects, injectors for pre-flight logic (logging, auth), and exception-based error handling.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install the Package Add the package to your Laravel project via Composer:

    composer require paypal/paypalhttp:1.0.1
    
  2. Set Up Environment Define your PayPal API environment (e.g., sandbox or live) in config/services.php:

    'paypal' => [
        'environment' => env('PAYPAL_ENVIRONMENT', 'sandbox'),
        'base_url' => env('PAYPAL_BASE_URL', 'https://api.sandbox.paypal.com'),
        'client_id' => env('PAYPAL_CLIENT_ID'),
        'client_secret' => env('PAYPAL_CLIENT_SECRET'),
    ],
    
  3. Register the Client Bind the HttpClient to Laravel’s service container in AppServiceProvider.php:

    use PayPalHttp\HttpClient;
    use PayPalHttp\Environment;
    
    public function register()
    {
        $this->app->singleton(HttpClient::class, function ($app) {
            $env = new Environment(config('services.paypal.base_url'));
            $client = new HttpClient($env);
    
            // Add injectors (e.g., logging, auth headers)
            $client->addInjector(new AuthInjector(
                config('services.paypal.client_id'),
                config('services.paypal.client_secret')
            ));
    
            return $client;
        });
    }
    
  4. First Use Case: Fetch Transactions Create a service to interact with PayPal’s API:

    use PayPalHttp\HttpRequest;
    use PayPalHttp\HttpClient;
    
    class PayPalService {
        public function __construct(private HttpClient $client) {}
    
        public function getTransactions()
        {
            $request = new HttpRequest('/v1/reporting/transactions', 'GET');
            $request->header('Authorization', 'Bearer ' . $this->getAccessToken());
    
            return $this->client->execute($request);
        }
    
        private function getAccessToken()
        {
            // Implement OAuth2 token retrieval logic
        }
    }
    
  5. Call the Service Use the service in a controller or command:

    use App\Services\PayPalService;
    
    public function index(PayPalService $paypal)
    {
        $response = $paypal->getTransactions();
        return response()->json($response->result);
    }
    

Implementation Patterns

Usage Patterns

  1. Request Construction Build requests dynamically based on API endpoints:

    $request = new HttpRequest('/v1/payments/payment', 'POST');
    $request->header('Content-Type', 'application/json');
    $request->body = json_encode(['intent' => 'sale', 'payer' => [...]]);
    
  2. Injectors for Cross-Cutting Concerns Use injectors to handle repetitive tasks like authentication, logging, or retries:

    class AuthInjector implements Injector {
        public function __construct(private string $clientId, private string $clientSecret) {}
    
        public function inject(HttpRequest $request)
        {
            if ($request->path === '/v1/oauth2/token') return;
    
            $request->header('Authorization', 'Bearer ' . $this->getAccessToken());
        }
    
        private function getAccessToken(): string
        {
            // Fetch and return OAuth token
        }
    }
    
  3. Response Handling Parse responses generically or use Laravel’s helpers:

    $response = $client->execute($request);
    if ($response->statusCode === 200) {
        $data = json_decode($response->result, true);
        return $data['transactions'];
    }
    throw new \RuntimeException('PayPal API error: ' . $response->result);
    
  4. Error Handling Wrap IOException in Laravel exceptions for consistency:

    try {
        $response = $client->execute($request);
    } catch (IOException $e) {
        throw new \Illuminate\Http\Client\ConnectionException(
            'PayPal API error: ' . $e->getMessage(),
            previous: $e
        );
    }
    

Workflows

  1. OAuth2 Flow Integration Use injectors to manage token refresh:

    class TokenInjector implements Injector {
        public function inject(HttpRequest $request)
        {
            if ($this->needsTokenRefresh()) {
                $this->refreshToken();
            }
            $request->header('Authorization', 'Bearer ' . $this->getToken());
        }
    }
    
  2. Idempotency Keys Add idempotency headers for safe retries:

    $request->header('Idempotency-Key', Str::uuid());
    
  3. Batch Processing Handle paginated responses:

    $request = new HttpRequest('/v1/reporting/transactions', 'GET');
    $request->query['count'] = 100;
    $request->query['start_index'] = 0;
    
    do {
        $response = $client->execute($request);
        $transactions = json_decode($response->result, true);
        // Process transactions
        $request->query['start_index'] += 100;
    } while ($response->statusCode === 200);
    

Integration Tips

  1. Laravel Facades Create a facade for cleaner syntax:

    // PayPalFacade.php
    class PayPalFacade extends \Illuminate\Support\Facades\Facade {
        protected static function getFacadeAccessor() { return 'paypal'; }
    }
    

    Register the facade in AppServiceProvider:

    $this->app->bind('paypal', function ($app) {
        return new PayPalService($app->make(HttpClient::class));
    });
    

    Usage:

    $transactions = PayPal::getTransactions();
    
  2. Testing Mock the HttpClient in tests:

    $mockClient = Mockery::mock(HttpClient::class);
    $mockClient->shouldReceive('execute')
        ->once()
        ->andReturn(new HttpResponse(200, [], '{"transactions": [...]}'));
    
    $this->app->instance(HttpClient::class, $mockClient);
    
  3. Logging Use injectors to log requests/responses:

    class LoggingInjector implements Injector {
        public function inject(HttpRequest $request)
        {
            \Log::debug('PayPal Request', [
                'path' => $request->path,
                'method' => $request->method,
                'headers' => $request->headers,
                'body' => $request->body,
            ]);
        }
    }
    
  4. Configuration Centralize PayPal config in config/paypal.php:

    return [
        'environments' => [
            'sandbox' => 'https://api.sandbox.paypal.com',
            'live' => 'https://api.paypal.com',
        ],
        'default' => env('PAYPAL_ENVIRONMENT', 'sandbox'),
        'auth' => [
            'client_id' => env('PAYPAL_CLIENT_ID'),
            'client_secret' => env('PAYPAL_CLIENT_SECRET'),
        ],
    ];
    

Gotchas and Tips

Pitfalls

  1. Deprecation Risk

    • The package is archived with no future updates. Plan for migration to PayPal’s Server SDK.
    • Mitigation: Document the deprecation in your codebase and set a migration deadline.
  2. Case-Sensitive Headers

    • The package has a known issue with case-sensitive header handling (fixed in v1.0.1). Ensure headers like Content-Type are lowercase.
    • Example:
      $request->header('content-type', 'application/json'); // Works
      $request->header('Content-Type', 'application/json'); // May fail
      
  3. Error Handling Quirks

    • IOException does not extend Laravel’s Exception hierarchy. Wrap it for consistency:
      catch (IOException $e) {
          throw new \RuntimeException(
              'PayPal API error [' . $e->response->statusCode . ']: ' . $e->response->result,
              0,
              $e
          );
      }
      
  4. No Built-in JSON Handling

    • The package does not automatically decode JSON responses. Manually decode:
      $data = json_decode($response->result, true);
      
  5. CURL Dependency

    • Requires ext-curl enabled. Add to php.ini or Dockerfile if missing:
      extension=curl
      
  6. No Retry Logic

    • Unlike Laravel’s HttpClient, this package lacks built-in retry mechanisms. Implement manually:
      $attempts = 0;
      while ($attempts < 3) {
          try {
              $response = $client->execute($request);
              break;
          } catch (IOException $e) {
              if ($att
      
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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui