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

Laravel Mollie Billing Laravel Package

graystackit/laravel-mollie-billing

Batteries-included Mollie billing for Laravel with VAT/OSS compliance, VIES validation, wallet-based metered billing, coupons, trials, scheduled plan changes, webhooks/mandates, admin panel, and a Livewire 4 customer portal—built around a Billable contract.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require graystackit/laravel-mollie-billing
    php artisan vendor:publish --tag=mollie-billing-config
    php artisan vendor:publish --tag=mollie-billing-migrations
    php artisan vendor:publish --tag=mollie-billing-views
    php artisan vendor:publish --tag=billing-lang
    php artisan migrate
    
  2. Configure .env

    BILLING_MOLLIE_KEY=test_xxxxxxxxxxxxxxxxxxxxxxxxxxxx
    BILLING_BILLABLE_MODEL=App\Models\Organization
    BILLING_BILLABLE_KEY_TYPE=uuid
    BILLING_USER_KEY_TYPE=int
    BILLING_CURRENCY=EUR
    
  3. Define Billable Model

    use GraystackIT\MollieBilling\Concerns\HasBilling;
    use GraystackIT\MollieBilling\Contracts\Billable;
    
    class Organization implements Billable {
        use HasBilling;
        public function getUsedBillingSeats(): int { return $this->users()->count(); }
    }
    
  4. Register Routes

    Route::middleware(['auth', 'tenant'])->group(fn () => MollieBilling::routes());
    Route::middleware(['auth'])->group(fn () => MollieBilling::checkoutRoutes());
    
  5. Set Up Resolvers

    MollieBilling::resolveBillableUsing(fn () => auth()->user()?->currentOrganization);
    MollieBilling::authUsing(fn () => auth()->check());
    

First Use Case

Trigger the checkout flow for a new organization:

$organization = Organization::create(['name' => 'Acme Corp']);
$checkoutUrl = MollieBilling::checkoutUrl($organization, 'basic');
return redirect($checkoutUrl);

Implementation Patterns

Core Workflows

  1. Subscription Management

    // Create a subscription
    $subscription = MollieBilling::createSubscription($billable, 'basic', [
        'addons' => ['seats' => 10],
        'coupon' => 'SUMMER20'
    ]);
    
    // Cancel a subscription
    $subscription->cancel();
    
    // Schedule a plan change
    $subscription->changePlan('pro', now()->addMonth());
    
  2. Wallet & Metered Billing

    // Charge for usage
    $wallet = $billable->wallet;
    $wallet->charge('api_calls', 100, 'EUR 0.01');
    
    // Refund overage
    $wallet->refund('api_calls', 50);
    
  3. Coupon Application

    // Apply a coupon during checkout
    $checkoutUrl = MollieBilling::checkoutUrl($billable, 'basic', coupon: 'SUMMER20');
    
    // Apply a coupon to an existing subscription
    $subscription->applyCoupon('SUMMER20');
    
  4. Feature Gating

    // Blade directive
    @planFeature('analytics')
    <div>Advanced Analytics</div>
    
    // Middleware
    Route::middleware(['auth', 'billing.feature:analytics'])->group(...);
    

Integration Tips

  • Webhooks: Handle Mollie webhooks via the MollieBilling::webhook() facade method.
  • Admin Panel: Use MollieBilling::adminRoutes() for a pre-built admin interface.
  • Customer Portal: Leverage the Livewire 4 portal with MollieBilling::routes().
  • Localization: Override translations via resources/lang/vendor/billing.
  • Custom Views: Publish and override Blade/Livewire views in resources/views/vendor/mollie-billing.

Example: Full Checkout Flow

// In AppServiceProvider::boot()
MollieBilling::createBillableUsing(function (array $data) {
    return Organization::create([
        'name' => $data['name'],
        'billing_street' => $data['billing_street'],
        // ... other fields
    ]);
});

// Trigger checkout
$billable = Organization::create(['name' => 'Acme Corp']);
$checkoutUrl = MollieBilling::checkoutUrl($billable, 'basic', coupon: 'SUMMER20');
return redirect($checkoutUrl);

Gotchas and Tips

Pitfalls

  1. Key Type Configuration

    • billable_key_type and user_key_type must be set before running migrations. Changing them later requires manual column alterations.
    • Example: If using uuid, ensure your wallets.holder_id column is also uuid.
  2. Tenant Resolution

    • The checkout route must not be nested under a tenant prefix. Use PropagateRouteDefaults middleware for tenant-aware contexts.
    • Example:
      Route::middleware(['auth', 'tenant'])->group(fn () => MollieBilling::routes());
      Route::middleware(['auth'])->group(fn () => MollieBilling::checkoutRoutes());
      
  3. VAT/OSS Compliance

    • Country mismatches (user-declared vs. payment-derived vs. IP-derived) trigger automatic cancellation. Use the admin panel to override.
    • B2B billables with VIES-validated VAT numbers bypass checks.
  4. Wallet Quotas

    • Overage charges require past_due state. Ensure your getUsedBillingSeats() method accurately reflects usage.
  5. Livewire Dependencies

    • Requires livewire/flux-pro (commercial license). Install separately:
      composer require livewire/flux-pro
      

Debugging

  • Config Validation: Run php artisan billing:check-config to catch syntax errors or broken references.
  • Webhook Testing: Use Mollie’s test mode and verify webhook signatures:
    MollieBilling::webhook($request, $payload);
    
  • Logs: Enable debug mode in config/mollie-billing.php:
    'debug' => env('BILLING_DEBUG', false),
    

Extension Points

  1. Custom Billable Logic

    • Override urlRouteParameters() on your billable model for dynamic URL generation.
    • Example:
      public function urlRouteParameters(): array {
          return ['organization' => $this->slug, 'custom' => 'param'];
      }
      
  2. Checkout Customization

    • Extend the Livewire checkout component by publishing views and overriding methods in your Organization model.
    • Example:
      public function getCheckoutData(): array {
          return array_merge(parent::getCheckoutData(), ['custom_field' => 'value']);
      }
      
  3. Coupon Engine

    • Add new coupon types by extending GraystackIT\MollieBilling\Contracts\Coupon.
    • Example:
      class CustomCoupon implements Coupon {
          public function apply(Billable $billable): void {
              // Custom logic
          }
      }
      
  4. Admin Panel Overrides

    • Publish and override the admin panel views in resources/views/vendor/mollie-billing/admin.
    • Example:
      php artisan vendor:publish --tag=mollie-billing-views
      

Tailwind CSS

Add the package’s Blade views to your Tailwind content config to avoid purging utility classes:

// vite.config.js
export default defineConfig({
    plugins: [
        tailwindcss({
            content: [
                './resources/views/**/*.blade.php',
                './vendor/graystackit/laravel-mollie-billing/**/*.blade.php',
            ],
        }),
    ],
});

Common Errors

Error Solution
Call to undefined method Ensure HasBilling trait is used and Billable contract is implemented.
Column not found Verify billable_key_type matches your database schema.
Flux Pro not found Install livewire/flux-pro separately.
Invalid coupon Check mollie-billing-plans.php for valid coupon codes.
Webhook signature mismatch Ensure MOLLIE_WEBHOOK_SECRET is set in .env.
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.
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
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours