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 Bundle Laravel Package

beelab/paypal-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the bundle via Composer:

    composer require beelab/paypal-bundle
    

    Enable it in config/bundles.php:

    BeeLab\PaypalBundle\BeeLabPaypalBundle::class => ['all' => true],
    
  2. Configuration Publish the default config:

    php bin/console beelab:paypal:install
    

    Update config/packages/beelab_paypal.yaml with your PayPal credentials (e.g., client_id, secret, mode: sandbox).

  3. First Use Case: Create a Payment Use the PaypalClient service in a controller:

    use BeeLab\PaypalBundle\Service\PaypalClient;
    
    class PaymentController extends AbstractController
    {
        public function createPayment(PaypalClient $paypalClient): Response
        {
            $payment = $paypalClient->createPayment([
                'intent' => 'sale',
                'payer' => ['payment_method' => 'paypal'],
                'transactions' => [[
                    'amount' => ['total' => '10.00', 'currency' => 'USD'],
                    'description' => 'Test payment',
                ]],
                'redirect_urls' => [
                    'return_url' => $this->generateUrl('payment_success'),
                    'cancel_url' => $this->generateUrl('payment_cancel'),
                ],
            ]);
            return $this->redirect($payment->getApprovalLink());
        }
    }
    
  4. Key Files to Review

    • config/packages/beelab_paypal.yaml: Configuration reference.
    • Resources/doc/index.md: Official documentation (e.g., webhooks, refunds).
    • Service/PaypalClient.php: Core API methods (e.g., createPayment(), executePayment()).

Implementation Patterns

Workflows

  1. Standard Checkout Flow

    • Step 1: Create a payment (unspecified intent) and redirect to PayPal.
      $payment = $paypalClient->createPayment($data);
      return $this->redirect($payment->getApprovalLink());
      
    • Step 2: Handle PayPal’s redirect back to your return_url (e.g., payment_success route).
      public function handleReturn(PaypalClient $paypalClient, Request $request): Response
      {
          $paymentId = $request->query->get('paymentId');
          $payerId = $request->query->get('PayerID');
          $payment = $paypalClient->executePayment($paymentId, $payerId);
          // Save transaction or update order status.
      }
      
  2. Subscription Management Use createPlan() and createSubscription() for recurring payments:

    $plan = $paypalClient->createPlan([
        'name' => 'Premium',
        'billing_cycles' => [[
            'frequency' => 'MONTH',
            'frequency_interval' => 1,
            'tenure_type' => 'REGULAR',
            'sequence' => 1,
            'amount' => ['currency' => 'USD', 'value' => '9.99'],
        ]],
    ]);
    $subscription = $paypalClient->createSubscription([
        'plan_id' => $plan->getId(),
        'start_time' => (new \DateTime())->format(\DateTime::ATOM),
    ]);
    
  3. Webhook Handling

    • Configure routes in config/routes.yaml to handle PayPal events (e.g., payment.capture.completed).
    • Use the PaypalWebhook service to verify and process events:
      use BeeLab\PaypalBundle\Service\PaypalWebhook;
      
      public function handleWebhook(PaypalWebhook $webhook, Request $request): Response
      {
          $event = $webhook->verifyAndParse($request->getContent());
          // Process $event->getResource() (e.g., capture, refund).
      }
      

Integration Tips

  • Dependency Injection: Prefer injecting PaypalClient over instantiating it directly.
  • Configuration Overrides: Extend the config in config/packages/beelab_paypal.yaml:
    beelab_paypal:
        client_id: '%env(PAYPAL_CLIENT_ID)%'
        secret: '%env(PAYPAL_SECRET)%'
        mode: '%env(PAYPAL_MODE)%' # 'sandbox' or 'live'
        webhook_id: '%env(PAYPAL_WEBHOOK_ID)%' # For webhook verification.
    
  • Environment Variables: Store sensitive keys in .env (e.g., PAYPAL_CLIENT_ID).
  • Testing: Use the sandbox mode and PayPal’s developer accounts for testing.

Gotchas and Tips

Pitfalls

  1. Webhook Verification

    • Issue: PayPal webhook events must be verified using the webhook_id and auth_algo/cert_url.
    • Fix: Ensure webhook_id is set in config and use PaypalWebhook::verifyAndParse():
      try {
          $event = $webhook->verifyAndParse($rawBody, $headers);
      } catch (\RuntimeException $e) {
          // Log and ignore unverified events.
      }
      
  2. Idempotency Keys

    • Issue: PayPal requires unique idempotency_key for createPayment() to avoid duplicate transactions.
    • Fix: Generate a UUID or use a database sequence:
      $paymentData = [
          'intent' => 'sale',
          'idempotency_key' => Str::uuid()->toString(),
          // ... other fields
      ];
      
  3. Currency and Amount Formatting

    • Issue: PayPal expects amounts as strings (e.g., "10.00", not 10 or 10.0).
    • Fix: Validate inputs or use number_format():
      $amount = number_format($order->getTotal(), 2, '.', '');
      
  4. Redirect URLs

    • Issue: return_url and cancel_url must be publicly accessible and HTTPS.
    • Fix: Use absolute URLs (e.g., https://yourdomain.com/payment/success).
  5. Subscription Billing Cycles

    • Issue: Incorrect tenure_type (e.g., REGULAR vs. TRIAL) can break subscriptions.
    • Fix: Test with PayPal’s subscription simulator.

Debugging

  • Enable Logging: Set debug: true in config to log PayPal API responses:
    beelab_paypal:
        debug: true
    
  • PayPal Sandbox Testing: Use the PayPal Sandbox Dashboard to simulate transactions and webhooks.
  • API Response Errors: Check PaypalClient exceptions for PayPal error details (e.g., INVALID_RECEIVER_EMAIL).

Extension Points

  1. Custom Event Handlers

    • Extend the PaypalWebhook service to add custom logic for specific events:
      $event = $webhook->verifyAndParse($rawBody);
      if ($event->getEventType() === 'PAYMENT.CAPTURE.COMPLETED') {
          $this->handleCaptureCompleted($event->getResource());
      }
      
  2. Custom Payment Data

    • Attach metadata to payments using the custom field:
      $paymentData = [
          'transactions' => [[
              'amount' => ['currency' => 'USD', 'total' => '10.00'],
              'custom' => json_encode(['order_id' => $order->getId()]),
          ]],
      ];
      
  3. Override Services

    • Replace the default PaypalClient with a decorator for additional logic:
      // src/Service/PaypalClientDecorator.php
      class PaypalClientDecorator implements PaypalClientInterface
      {
          private $decorated;
      
          public function __construct(PaypalClient $decorated)
          {
              $this->decorated = $decorated;
          }
      
          public function createPayment(array $data)
          {
              $data['custom'] = json_encode(['extra' => 'metadata']);
              return $this->decorated->createPayment($data);
          }
      }
      
    • Register the decorator in services.yaml:
      services:
          BeeLab\PaypalBundle\Service\PaypalClientInterface: '@App\Service\PaypalClientDecorator'
      
  4. Add New API Methods

    • Extend the bundle by creating a custom service that uses the underlying Paypal\Api\ classes:
      use Paypal\Api\Refund
      
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