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

Payment Laravel Package

shopper/payment

Laravel payment package for Shopper: unified API to manage gateways, transactions, refunds, and payment statuses. Provides configurable drivers, events, and webhooks to integrate checkout flows with your app and keep payments in sync across providers.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require shopper/payment
    

    Publish the config file:

    php artisan vendor:publish --provider="Shopper\Payment\PaymentServiceProvider" --tag="config"
    
  2. Configuration Edit config/payment.php to define your preferred payment gateways (e.g., Stripe, PayPal, or custom providers). Example:

    'gateways' => [
        'stripe' => [
            'key' => env('STRIPE_KEY'),
            'secret' => env('STRIPE_SECRET'),
        ],
        'paypal' => [
            'client_id' => env('PAYPAL_CLIENT_ID'),
            'secret' => env('PAYPAL_SECRET'),
        ],
    ],
    
  3. First Use Case: Creating a Payment Resolve the payment service in a controller or service:

    use Shopper\Payment\Facades\Payment;
    
    public function createPayment()
    {
        $payment = Payment::create('stripe', [
            'amount' => 1000, // $10.00
            'currency' => 'USD',
            'description' => 'Order #12345',
            'metadata' => ['order_id' => 12345],
        ]);
    
        return $payment->getCheckoutUrl(); // Redirect or return URL
    }
    
  4. Webhook Handling Define a route for handling payment webhooks (e.g., POST /payment/webhook). Use the Payment::handleWebhook() method to process events:

    public function handleWebhook(Request $request)
    {
        Payment::handleWebhook($request, function ($event) {
            // Handle successful/failed payments
            if ($event->type === 'payment.succeeded') {
                // Update order status, send confirmation, etc.
            }
        });
    }
    

Implementation Patterns

Core Workflows

  1. Payment Creation & Processing

    • Use Payment::create($gateway, $data) to initialize a payment. The $data array should include:
      • amount (integer in cents)
      • currency (ISO 3-letter code)
      • description (optional)
      • metadata (key-value pairs for tracking)
    • For Stripe, include payment_method_id if using tokens:
      $payment = Payment::create('stripe', [
          'amount' => 2000,
          'currency' => 'USD',
          'payment_method_id' => $token,
      ]);
      
  2. Subscription Management

    • Create subscriptions via Payment::createSubscription($gateway, $data):
      $subscription = Payment::createSubscription('stripe', [
          'price_id' => 'price_123',
          'customer_id' => 'cus_123',
      ]);
      
    • Cancel subscriptions with Payment::cancelSubscription($gateway, $subscriptionId).
  3. Refunds & Captures

    • Refund a payment:
      Payment::refund('stripe', $paymentId, ['amount' => 500]);
      
    • Capture an authorized payment:
      Payment::capture('stripe', $paymentId, ['amount' => 1000]);
      
  4. Webhook Events

    • Subscribe to events in handleWebhook():
      Payment::handleWebhook($request, function ($event) {
          switch ($event->type) {
              case 'payment.succeeded':
                  // Fulfill order
                  break;
              case 'payment.failed':
                  // Notify user
                  break;
              case 'invoice.payment_succeeded':
                  // Update subscription
                  break;
          }
      });
      
    • Validate events with Payment::validateWebhook($request).

Integration Tips

  1. Laravel Events Dispatch custom events after payment actions:

    event(new \App\Events\PaymentSucceeded($payment));
    
  2. Middleware for Auth Protect payment routes with Laravel middleware (e.g., auth:sanctum):

    Route::post('/payment/webhook', [PaymentController::class, 'handleWebhook'])
        ->middleware('auth:sanctum');
    
  3. Testing Use mock gateways in tests:

    Payment::shouldReceive('create')->with('stripe', [...])->andReturn($mockPayment);
    
  4. Logging Enable debug logging in config/payment.php:

    'debug' => env('APP_ENV') === 'local',
    
  5. Custom Gateways Extend the base Gateway class to support new providers:

    namespace App\Providers;
    
    use Shopper\Payment\Contracts\Gateway;
    
    class CustomGateway implements Gateway {
        public function create(array $data) { ... }
        public function handleWebhook(array $payload) { ... }
    }
    

    Register in config/payment.php:

    'gateways' => [
        'custom' => \App\Providers\CustomGateway::class,
    ],
    

Gotchas and Tips

Pitfalls

  1. Gateway Configuration

    • Issue: Forgetting to set env() variables for gateway keys/secrets.
    • Fix: Use .env.example to document required variables and validate config on boot:
      if (!config('payment.gateways.stripe.key')) {
          throw new \RuntimeException('Stripe key not configured.');
      }
      
  2. Webhook Validation

    • Issue: Skipping webhook signature validation (e.g., Stripe’s stripe-signature header).
    • Fix: Always validate in handleWebhook():
      if (!Payment::validateWebhook($request)) {
          abort(403, 'Invalid webhook signature');
      }
      
  3. Currency/Amount Mismatch

    • Issue: Passing amount as dollars instead of cents (e.g., 10.00 vs. 1000).
    • Fix: Document this in your team’s coding standards and add a validation rule:
      $validator = Validator::make($data, [
          'amount' => 'required|integer|min:1',
      ]);
      
  4. Idempotency

    • Issue: Retrying failed payments without idempotency keys can cause duplicate charges.
    • Fix: Use the idempotency_key field in payment requests:
      Payment::create('stripe', [
          'amount' => 1000,
          'idempotency_key' => uniqid(),
      ]);
      
  5. Gateway-Specific Quirks

    • PayPal: Requires intent (e.g., sale, authorize) in the data array.
    • Stripe: Uses payment_method_types (e.g., card) for payment methods.
    • Fix: Refer to the package’s gateway adapters for provider-specific requirements.

Debugging Tips

  1. Enable Debug Mode Set 'debug' => true in config/payment.php to log raw API responses.

  2. Inspect Events Dump webhook payloads for debugging:

    Payment::handleWebhook($request, function ($event) {
        \Log::debug('Webhook event:', $event->toArray());
    });
    
  3. Test with Sandbox Always test payments in sandbox mode (e.g., Stripe’s test cards: 4242 4242 4242 4242).

  4. Check for Deprecations Monitor the package’s release notes for breaking changes (e.g., Stripe API version updates).


Extension Points

  1. Custom Event Handling Extend the PaymentEvent class to add provider-specific data:

    namespace App\Events;
    
    use Shopper\Payment\Events\PaymentEvent;
    
    class CustomPaymentEvent extends PaymentEvent {
        public function getCustomField() { ... }
    }
    
  2. Gateway Decorators Wrap gateways to add pre/post-processing:

    Payment::extend('stripe', function ($app) {
        return new class($app['payment.stripe']) {
            public function create(array $data) {
                // Add custom logic (e.g., logging)
                return $this->gateway->create($data);
            }
        };
    });
    
  3. Service Provider Binding Override the default service binding in your app’s AppServiceProvider:

    public function register()
    {
        $this->app->bind(\Shopper\Payment\Contracts\Payment::class, function ($app) {
            return new \App\Services\CustomPaymentService($app);
        });
    }
    
  4. Macros for Facade

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