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

Paypal Laravel Package

omnipay/paypal

PayPal gateway driver for the Omnipay PHP payments library. Supports Express Checkout (including In-Context), Website Payments Pro, and PayPal REST API. Install via Composer and use with Omnipay for framework-agnostic payment processing.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:
    composer require omnipay/paypal
    
  2. Configure credentials in config/services.php:
    'paypal' => [
        'client_id'     => env('PAYPAL_CLIENT_ID'),
        'secret'        => env('PAYPAL_SECRET'),
        'sandbox'       => env('PAYPAL_SANDBOX', false),
        'rest_endpoint' => env('PAYPAL_REST_ENDPOINT', 'https://api.paypal.com'),
    ],
    
  3. Create a gateway service (e.g., app/Services/PayPalService.php):
    use Omnipay\Omnipay;
    
    class PayPalService {
        public function __construct() {
            $this->gateway = Omnipay::create('PayPal_Rest');
            $this->gateway->setClientId(config('services.paypal.client_id'));
            $this->gateway->setSecret(config('services.paypal.secret'));
            $this->gateway->setTestMode(config('services.paypal.sandbox'));
        }
    
        public function getGateway() {
            return $this->gateway;
        }
    }
    
  4. Register the service in AppServiceProvider:
    public function register() {
        $this->app->singleton(PayPalService::class);
    }
    

First Use Case: Express Checkout

  1. Initialize a purchase request:
    $gateway = app(PayPalService::class)->getGateway();
    $request = $gateway->purchase([
        'amount' => '10.00',
        'currency' => 'USD',
        'returnUrl' => route('paypal.return'),
        'cancelUrl' => route('paypal.cancel'),
    ]);
    
  2. Redirect to PayPal:
    $response = $request->send();
    $response->redirect(); // Redirects to PayPal
    
  3. Handle the return (e.g., in PaypalReturnController):
    $gateway = app(PayPalService::class)->getGateway();
    $request = $gateway->completePurchase([
        'token' => $request->query->get('token'),
    ]);
    $response = $request->send();
    if ($response->isSuccessful()) {
        // Save transaction to DB
        $transaction = $response->getTransactionReference();
        // Mark order as paid
    }
    

Implementation Patterns

Workflows

1. One-Time Payments (Express Checkout)

  • Flow:
    1. User adds item to cart → trigger purchase().
    2. Redirect to PayPal → user authorizes payment.
    3. PayPal redirects back → call completePurchase().
    4. Save transactionReference (from completePurchase() response) to DB.
  • Laravel Integration:
    • Use middleware to validate PayPal’s return URL.
    • Store transactions in an orders table with paypal_transaction_id field.
    • Example:
      // app/Http/Controllers/PaypalController.php
      public function return(Request $request) {
          $gateway = app(PayPalService::class)->getGateway();
          $response = $gateway->completePurchase([
              'token' => $request->token,
          ])->send();
      
          if ($response->isSuccessful()) {
              Order::find($request->order_id)->update([
                  'paid_at' => now(),
                  'transaction_id' => $response->getTransactionReference(),
              ]);
          }
          return redirect()->route('order.success');
      }
      

2. Refunds

  • Flow:
    1. Fetch transaction details → refund using PayPal_Rest gateway.
    2. Example:
      $gateway = app(PayPalService::class)->getGateway();
      $request = $gateway->refund([
          'amount' => '5.00',
          'transactionReference' => 'PAY-123ABC', // From DB
      ]);
      $response = $request->send();
      if ($response->isSuccessful()) {
          // Update order status
      }
      

3. Webhooks (IPN/REST)

  • Pattern: Use Laravel middleware to verify PayPal signatures.
  • Example:
    // app/Http/Middleware/VerifyPayPalWebhook.php
    public function handle($request, Closure $next) {
        $gateway = app(PayPalService::class)->getGateway();
        $request->validate([
            'auth_algo' => 'required',
            'cert_url' => 'required',
            'txn_id' => 'required',
            'txn_type' => 'required',
            'notify_version' => 'required',
            'verify_sign' => 'required',
        ]);
    
        $verified = $gateway->validateWebhook($request->all());
        if (!$verified) {
            abort(403, 'Invalid PayPal webhook signature');
        }
        return $next($request);
    }
    
  • Register middleware in app/Http/Kernel.php:
    protected $routeMiddleware = [
        'verify.paypal' => \App\Http\Middleware\VerifyPayPalWebhook::class,
    ];
    

4. Error Handling

  • Centralize exceptions in a service class:
    // app/Services/PayPalService.php
    public function handlePayment($requestData) {
        try {
            $response = $this->gateway->purchase($requestData)->send();
            return $response;
        } catch (\Omnipay\Common\Exception\InvalidResponseException $e) {
            \Log::error('PayPal error: ' . $e->getMessage());
            throw new \App\Exceptions\PaymentFailedException('Payment processing failed');
        }
    }
    

Integration Tips

  1. Use PayPal_Rest for New Projects:
    • Avoid PayPal_Express/PayPal_Pro (deprecated APIs). Focus on REST for future compatibility.
  2. Leverage Laravel’s Queue System:
    • Offload async operations (e.g., refunds, webhook processing) to queues:
      // Dispatch a job after refund
      RefundProcessed::dispatch($order, $response);
      
  3. Store Transactions in a Dedicated Table:
    • Example schema:
      Schema::create('paypal_transactions', function (Blueprint $table) {
          $table->id();
          $table->string('transaction_reference');
          $table->string('status');
          $table->json('metadata');
          $table->timestamps();
      });
      
  4. Test with PayPal Sandbox:
    • Use PayPal’s sandbox accounts for testing.
    • Enable test mode in config:
      'sandbox' => env('PAYPAL_SANDBOX', true),
      

Gotchas and Tips

Pitfalls

  1. Transaction Reference Mismatch:

    • Issue: purchase() returns a token, but completePurchase() returns the actual transactionReference. Always use the latter for refunds.
    • Fix: Store the transactionReference from completePurchase() in your DB.
      $transactionRef = $response->getTransactionReference(); // Correct for refunds
      
  2. Deprecated Classic APIs:

    • Issue: PayPal_Express and PayPal_Pro use PayPal Classic APIs, which are end-of-life. PayPal may block requests.
    • Fix: Use PayPal_Rest exclusively. If you must use Classic APIs, monitor PayPal’s deprecation timeline and migrate.
  3. Webhook Validation:

    • Issue: PayPal IPN/REST webhooks require signature verification. The package does not handle this automatically.
    • Fix: Implement custom validation (e.g., using openssl_verify for IPN or PayPal’s REST API signature headers).
  4. DateTime Formatting:

    • Issue: PayPal expects EXPDATE and STARTDATE as 6-digit strings (e.g., 1225 for December 2025).
    • Fix: Format dates manually:
      $expiryDate = '1225'; // YYMM format
      
  5. Recurring Payments Not Supported:

    • Issue: This package does not support PayPal’s Billing Agreements or Subscriptions API.
    • Fix: Use PayPal’s official PHP SDK or a service like Chargebee for subscriptions.
  6. TLS 1.2 Requirement:

    • Issue: PayPal enforces TLS 1.2. Older PHP versions (e.g., < 5.6) may fail.
    • Fix: Ensure your server uses TLS 1.2:
      // In bootstrap/app.php
      
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.
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
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver