Skip to main content

Seat-Based Subscriptions

Seat-based subscriptions allow for dynamic pricing and usage limits based on how many "seats" a user occupies, such as team members, projects, or other custom metrics.

Configuration​

Seat types are configured in your config/peak.php file:

'subscription' => [
'seat_types' => [
'Team' => \Qoraiche\Peak\Services\Billing\SeatCalculators\TeamSeatCalculator::class,
// Add custom seat types here
],
],

The key (e.g., 'Team') should match the Seat Name field on your subscription plans in the admin panel.


Example Seat Calculator​

Here is an example implementation that counts the number of teams a user belongs to:

<?php

namespace Qoraiche\Peak\Services\Billing\SeatCalculators;

use Qoraiche\Peak\Services\Billing\Contracts\SeatCalculatorInterface;

class TeamSeatCalculator implements SeatCalculatorInterface
{
public function calculateSeats($user): int
{
return $user->teams()->count();
}
}

Interface Reference​

To create your own seat logic, implement the SeatCalculatorInterface:

namespace Qoraiche\Peak\Services\Billing\Contracts;

interface SeatCalculatorInterface
{
public function calculateSeats($user): int;
}

Seat Calculation Engine​

SeatPricing​

This service handles the logic of fetching the correct seat calculator and computing seat usage for a given user and plan.

use Qoraiche\Peak\Services\Billing\SeatPricing;

$seats = app(SeatPricing::class)->calculateSeats($user, $plan);

You typically don’t need to modify this class. It dynamically resolves the calculator using the plan's seat name.


Enforcing Plan Eligibility Based on Seat Count​

SeatEligibility​

This service checks whether a user is eligible to use a given plan based on their current seat usage.

If the user exceeds the maximum allowed seats defined in the plan, a validation exception is thrown.

use Qoraiche\Peak\Services\Billing\SeatEligibility;

app(SeatEligibility::class)->checkPlanEligibility($user, $plan);

Extending Plan Eligibility Logic​

PlanEligibilityChecker​

This class allows developers to hook into the plan eligibility validation system with their own rules.

You can register your own callbacks in a service provider like this:

use Qoraiche\Peak\Services\Billing\PlanEligibilityChecker;

public function boot(): void
{
PlanEligibilityChecker::register(function ($user, $plan) {
// Example custom rule: prevent downgrading to a free plan if user has active data
if ($plan->price === 0 && $user->projects()->exists()) {
throw \Illuminate\Validation\ValidationException::withMessages([
'plan' => 'You must delete your projects before switching to the free plan.',
]);
}
});
}

This will run alongside the built-in seat validation from SeatEligibility.


Summary​

ClassRole
SeatCalculatorInterfaceInterface for building custom seat calculators
SeatPricingCalculates seat usage using configured seat calculators
SeatEligibilityEnsures the user does not exceed allowed seats for selected plan
PlanEligibilityCheckerAllows custom eligibility checks by registering callbacks