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

Filament Cashier Billing Provider Laravel Package

maartenpaauw/filament-cashier-billing-provider

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Run composer require maartenpaauw/filament-cashier-billing-provider:^3.1.0 and publish the config:

    php artisan vendor:publish --provider="MaartenPaauw\FilamentCashierBillingProvider\FilamentCashierBillingProviderServiceProvider"
    
  2. Register the Provider Add the provider to your PanelServiceProvider (or AppServiceProvider):

    public function panel(Panel $panel): Panel
    {
        return $panel
            ->providers([
                \MaartenPaauw\FilamentCashierBillingProvider\FilamentCashierBillingProvider::make(),
            ]);
    }
    
  3. First Use Case: Display Subscription Status Ensure your User model (or Billable model) uses HasApiTokens and HasBilling traits. Then, add a widget to your Filament dashboard:

    use MaartenPaauw\FilamentCashierBillingProvider\Widgets\SubscriptionStatusWidget;
    
    public function widgets(Panel $panel): array
    {
        return [
            SubscriptionStatusWidget::class,
        ];
    }
    

Implementation Patterns

Core Workflows

  1. Subscription Management Use the built-in Resources to manage subscriptions directly in Filament:

    use MaartenPaauw\FilamentCashierBillingProvider\Resources\SubscriptionResource;
    
    public function resources(Panel $panel): array
    {
        return [
            SubscriptionResource::class,
        ];
    }
    
    • Supports CRUD for subscriptions, invoices, and payment methods.
    • Pre-configured with Filament’s table, form, and widget components.
  2. Customizing Subscription Fields Extend the SubscriptionResource or override fields in your panel:

    public function form(Form $form): Form
    {
        return $form
            ->schema([
                // Custom fields or overrides
                TextInput::make('custom_field')->rules(['required']),
                // ... other fields
            ]);
    }
    
  3. Multi-Tenant Billing Leverage Filament’s tenant system to scope billing data:

    public function getRelations(): array
    {
        return [
            RelationManager::make('subscriptions')
                ->for(\MaartenPaauw\FilamentCashierBillingProvider\Models\Subscription::class)
                ->title('Subscriptions')
                ->canView(function (User $user) {
                    return $user->can('viewSubscriptions');
                }),
        ];
    }
    
  4. Webhook Handling Use Filament’s Notifications to display Stripe webhook events:

    use MaartenPaauw\FilamentCashierBillingProvider\Notifications\SubscriptionWebhookNotification;
    
    // Trigger in your Stripe webhook controller:
    SubscriptionWebhookNotification::dispatch($event);
    

Integration Tips

  • Sync with Existing Models If your Billable model isn’t User, configure the provider in config/filament-cashier-billing-provider.php:

    'model' => \App\Models\Customer::class,
    
  • Localization Override translations in resources/lang/vendor/filament-cashier-billing-provider:

    'subscription_status' => [
        'active' => 'Active Subscription',
        'canceled' => 'Canceled',
        // ...
    ],
    
  • Permissions Use Filament’s Policies to restrict access:

    public static function getPages(): array
    {
        return [
            'subscriptions' => [
                'view' => 'viewSubscriptions',
                'create' => 'createSubscription',
            ],
        ];
    }
    

Gotchas and Tips

Pitfalls

  1. Model Mismatch

    • Issue: If your Billable model isn’t properly configured with HasApiTokens and HasBilling, the provider will throw errors.
    • Fix: Verify your model uses:
      use Laravel\Cashier\Billable;
      use Illuminate\Foundation\Auth\User as Authenticatable;
      
      class Customer extends Authenticatable implements Billable
      {
          use HasApiTokens, HasBilling;
      }
      
  2. Stripe Key Configuration

    • Issue: Forgetting to set STRIPE_KEY and STRIPE_SECRET in .env will cause silent failures.
    • Fix: Ensure these are set and the provider is configured in config/filament-cashier-billing-provider.php:
      'stripe' => [
          'key' => env('STRIPE_KEY'),
          'secret' => env('STRIPE_SECRET'),
      ],
      
  3. Webhook Verification

    • Issue: Stripe webhooks may fail if the signing secret doesn’t match.
    • Fix: Use the STRIPE_WEBHOOK_SECRET in your webhook endpoint:
      $payload = request()->getContent();
      $sigHeader = request()->header('Stripe-Signature');
      $event = \Stripe\Webhook::constructEvent($payload, $sigHeader, env('STRIPE_WEBHOOK_SECRET'));
      
  4. Laravel 11 Deprecation

    • Issue: This package no longer supports Laravel 11. Ensure your project is upgraded to Laravel 12 or 13.
    • Fix: Update your Laravel version:
      composer require laravel/framework:^13.0
      
  5. Caching Subscriptions

    • Issue: Frequent API calls to Stripe can slow down your admin panel.
    • Fix: Cache subscription data in your Billable model:
      public function getSubscriptionAttribute()
      {
          return cache()->remember("subscription-{$this->id}", now()->addHours(1), function () {
              return $this->stripe_subscription;
          });
      }
      

Debugging Tips

  1. Log Webhook Events Enable logging in config/filament-cashier-billing-provider.php:

    'logging' => [
        'enabled' => true,
        'channel' => 'single',
    ],
    

    Check logs in storage/logs/filament-cashier-billing-provider.log.

  2. Test Mode Use Stripe’s test mode for development:

    config(['services.stripe.test_mode' => true]);
    
  3. Widget Visibility If the SubscriptionStatusWidget doesn’t appear, ensure:

    • The widget is registered in widgets().
    • The authenticated user has the viewSubscriptions permission.

Extension Points

  1. Custom Widgets Extend the base widget to add functionality:

    class CustomSubscriptionWidget extends SubscriptionStatusWidget
    {
        protected function getHeaderActions(): array
        {
            return [
                Action::make('cancelSubscription')
                    ->action(fn () => $this->cancelSubscription())
                    ->requiresConfirmation(),
            ];
        }
    
        protected function cancelSubscription()
        {
            $this->user->cancelSubscription();
            $this->dispatchBrowserEvent('alert', ['type' => 'success', 'message' => 'Subscription canceled.']);
        }
    }
    
  2. Override Resource Classes Replace the default SubscriptionResource with a custom class:

    'resources' => [
        'subscription' => \App\Filament\Resources\CustomSubscriptionResource::class,
    ],
    
  3. Add Custom Actions Attach actions to subscription records:

    public static function getTableActions(): array
    {
        return [
            Action::make('resendInvoice')
                ->action(function (Subscription $record) {
                    $record->invoice()->resend();
                }),
        ];
    }
    
  4. Hook into Events Listen for Cashier events to trigger Filament notifications:

    use MaartenPaauw\FilamentCashierBillingProvider\Notifications\SubscriptionFailedNotification;
    
    event(new \Laravel\Cashier\Events\SubscriptionFailed($user, $exception));
    // Automatically triggers the notification if configured.
    

Laravel 13 and PHP 8.5 Compatibility

  • New Features: This release ensures full compatibility with Laravel 13 and PHP 8.5, leveraging the latest Cashier 16 features.
  • Type Safety: PHP 8.5’s stricter typing may require updates to custom extensions (e.g., custom resources or widgets).
  • Testing: Use PHP 8.5 and Laravel 13 for development to avoid compatibility issues.
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.
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
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle