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, an admin panel, and a Livewire 4 customer portal for any Billable model.
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 migrate
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
Set Up Routes (in routes/web.php):
Route::middleware(['web', 'auth', 'tenant'])->group(function () {
MollieBilling::routes(); // Customer portal
});
Route::middleware(['web', 'auth'])->group(function () {
MollieBilling::checkoutRoutes(); // Checkout flow
});
Implement Billable Contract:
use GraystackIT\MollieBilling\Concerns\HasBilling;
use GraystackIT\MollieBilling\Contracts\Billable;
class Organization extends Model implements Billable
{
use HasBilling;
public function getUsedBillingSeats(): int
{
return $this->users()->count();
}
}
Resolve Billable in AppServiceProvider:
MollieBilling::resolveBillableUsing(fn () => auth()->user()?->currentOrganization);
MollieBilling::authUsing(fn () => auth()->check());
Validate Config:
php artisan billing:check-config
Trigger the checkout flow for a user:
use GraystackIT\MollieBilling\Facades\MollieBilling;
$organization = new Organization();
MollieBilling::checkout($organization, 'basic-plan');
Subscription Management:
$subscription = MollieBilling::createSubscription($billable, 'premium-plan');
$subscription->cancel();
$subscription->updatePlan('pro-plan', ['addon1', 'addon2']);
Wallet-Based Metered Billing:
$wallet = $billable->wallet();
$wallet->charge('api_calls', 100, ['price' => 0.01]);
$wallet->handleOverages(); // Automatically charges overages
Coupon Application:
MollieBilling::checkout($billable, 'basic-plan', coupon: 'SUMMER20');
Plan Changes:
$subscription->schedulePlanChange('basic-plan', now()->addMonth());
Refunds and Credits:
$subscription->refund(100.00, 'Customer requested refund');
$billable->applyCredits(50.00, 'Trial extension');
Feature Gating:
Use the @planFeature Blade directive to restrict access:
@planFeature('analytics')
<div>Analytics Dashboard</div>
@endplanFeature
Checkout Flow:
Customize the checkout steps by overriding Livewire components in resources/views/vendor/mollie-billing/.
Admin Panel: Extend the admin panel by publishing and overriding views:
php artisan vendor:publish --tag=mollie-billing-views
Webhooks:
Handle Mollie webhooks by extending the MollieBillingServiceProvider:
MollieBilling::extendWebhookHandling(function ($event, $payload) {
// Custom logic for specific events
});
Localization: Override translations:
php artisan vendor:publish --tag=billing-lang
URL Generation: Generate signed promotion links:
$url = MollieBilling::promotionUrl($billable, 'basic-plan', 'SUMMER20');
Key Type Configuration:
billable_key_type and user_key_type must be set before running migrations. Changing them later requires manual column alterations.Tenant Resolution:
PropagateRouteDefaults middleware is applied to tenant-scoped routes to propagate route parameters (e.g., organization:slug) into generated URLs.Checkout Flow:
resolveBillableUsing returns null, the package falls back to query parameters (e.g., ?organization=acme-corp).Wallet Integration:
wallets.holder_id and related columns to match billable_key_type. Ensure your migrations align with this.Coupon Validation:
Recurring coupon on a SinglePayment plan) will throw errors.VAT/OSS Compliance:
Livewire Dependencies:
livewire/flux-pro (commercial license). Ensure it’s installed separately:
composer require livewire/flux-pro
Tailwind CSS:
content config to avoid purging utility classes:
// vite.config.js
content: [
'./resources/views/**/*.blade.php',
'./vendor/graystackit/laravel-mollie-billing/resources/views/**/*.blade.php',
],
Config Validation:
Use php artisan billing:check-config to catch syntax errors or misconfigurations early.
Webhook Debugging:
Enable Mollie webhook logging in config/mollie-billing.php:
'webhook_logging' => true,
Subscription States: Check subscription statuses via the admin panel or directly:
$subscription->status; // 'active', 'cancelled', 'past_due', etc.
Wallet Transactions: Audit wallet transactions:
$wallet->transactions()->latest()->get();
Custom Billable Creation:
Override createBillableUsing to customize billable creation logic (e.g., attach users or set default values).
Checkout Hooks:
Use beforeCheckoutUsing and afterCheckoutUsing to run logic before/after checkout (e.g., user creation or cleanup).
Orphaned Billable Cleanup:
Register a closure for cleanupOrphanedBillablesUsing to handle cascading deletes for abandoned checkouts.
Webhook Handling:
Extend webhook logic via extendWebhookHandling for custom event processing.
URL Parameter Resolution:
Override urlParametersUsing or urlRouteParameters() for custom URL generation logic in non-request contexts.
Feature Keys:
Extend feature keys in config/mollie-billing-plans.php to add new plan features.
Localization:
Override translations in resources/lang/vendor/billing/ to customize messages.
Views: Publish and override Livewire/Blade views for full customization of the portal, checkout, or admin panel.
How can I help you explore Laravel packages today?