Integrating Multi-Tenancy with Laravel Spark: Handling Subscriptions and Trial Periods

What I am trying to do: I am integrating FilamentPHP's multi-tenancy features with Laravel Spark. I want to ensure that the application correctly handles trial periods as configured in Laravel Spark. This solution works. What I did: I implemented a custom middleware named CheckTenantSubscription to check whether a tenant has an active subscription or is within their trial period, redirecting them to the billing page if neither condition is met. In this middleware, I used Filament::getTenant() to retrieve the tenant's information, and then proceeded to check their subscription status and trial period against the current date and time. My issue/the error: Using FilamentPHP's ->requiresTenantSubscription() seems to ignore Laravel Spark’s trial period. I expected it to consider the trial period automatically during subscription checks. In my middleware, I’ve explicitly handled trial and subscription checks. However, I’m uncertain if this aligns with FilamentPHP standards, especially when integrated with Laravel Spark. I am looking for guidance on whether there is a standard or more "Filament" way to handle this scenario. Code:
public function handle(Request $request, Closure $next): Response
{
$tenant = Filament::getTenant();

if (!$tenant) {
return $next($request);
}

// Check if the tenant is within their trial period
if ($tenant->trial_ends_at && Carbon::now()->lessThan($tenant->trial_ends_at)) {
return $next($request);
}

// Check for active subscription
if (!$tenant->subscribed()) {
return redirect()->route('spark.portal', ['type' => 'team', 'id' => $tenant->id]);
}

return $next($request);
}
public function handle(Request $request, Closure $next): Response
{
$tenant = Filament::getTenant();

if (!$tenant) {
return $next($request);
}

// Check if the tenant is within their trial period
if ($tenant->trial_ends_at && Carbon::now()->lessThan($tenant->trial_ends_at)) {
return $next($request);
}

// Check for active subscription
if (!$tenant->subscribed()) {
return redirect()->route('spark.portal', ['type' => 'team', 'id' => $tenant->id]);
}

return $next($request);
}
2 Replies
nizlee
nizlee10mo ago
@Donnell Wyche did you ever find a solution for this?
Donnell Wyche
Donnell WycheOP10mo ago
I created a OnTrialMiddel Middleware. My specific application logic is missing, but you can see what I did here. Not sure if it's the best FilamentPHP approach, but like everything else, it works.
class OnTrialMiddleware
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
if (auth()->check() && auth()->user()->team && auth()->user()->team->trial_ends_at > now()) {
FilamentView::registerRenderHook(
'panels::global-search.before', function () {
return View::make('filament.banner.badge', [
'trialEndsAt' => auth()->user()->team->trial_ends_at,
]);
}
);
}

return $next($request);
}
}
class OnTrialMiddleware
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
if (auth()->check() && auth()->user()->team && auth()->user()->team->trial_ends_at > now()) {
FilamentView::registerRenderHook(
'panels::global-search.before', function () {
return View::make('filament.banner.badge', [
'trialEndsAt' => auth()->user()->team->trial_ends_at,
]);
}
);
}

return $next($request);
}
}
Want results from more Discord servers?
Add your server