Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

digital@thirtythree.co.uk's avatar

How to limit access to a Free plan?

I've successfully set up some plan-switch limits with Spark::checkPlanEligibilityUsing. However, I have a few Free plans (also defined in Stripe) and this function never seems to fire upon switching to those plans (Beta & Free).

My user with 12 domains, can not switch to Lite ($5) but can switch to Free ($0).

        Spark::checkPlanEligibilityUsing(function ($user, $plan) {
            if ($plan->name == 'Beta' && count($user->domains) > 1000) {
                throw IneligibleForPlan::because('You have too many domains.');
            }
            elseif ($plan->name == 'Free' && count($user->domains) > 5) {
                throw IneligibleForPlan::because('You have too many domains.');
            }
            elseif ($plan->name == 'Lite' && count($user->domains) > 10) {
                throw IneligibleForPlan::because('You have too many domains.');
            }
            elseif ($plan->name == 'Basic' && count($user->domains) > 50) {
                throw IneligibleForPlan::because('You have too many domains.');
            }
            elseif ($plan->name == 'Pro' && count($user->domains) > 250) {
                throw IneligibleForPlan::because('You have too many domains.');
            }
            elseif ($plan->name == 'Enterprise' && count($user->domains) > 1000) {
                throw IneligibleForPlan::because('You have too many domains.');
            }
            return true;
        });
0 likes
3 replies
EventFellows's avatar

I have not worked with the Spark::checkPlanEligibilityUsing() setup myself yet but I do know that free spark plans are handled differently in spark than paid ones.

As far as I recall plans with a price of 0 are not pushed to Stripe but are only handled locally on the DB (that might also explain why you are not seeing some of the events you expect)

I also believe I remember that technically there is not such thing as a free plan but the absence of a paid plan is treated as being on the free plan.

(my comment relates to Spark version 1.0 when I investigated that aspect but I would be surprised if the mindset of the plan setup changed since then. You m might want to check the code for that)

digital@thirtythree.co.uk's avatar

Yes ok. I do have a method which deals with this in the rest of my app - it looks up the users' plan if current_billing_plan is not set.

The problem I have here then, is that I'm not sure how the booted method in the SparkServiceProvider gets the chosen plan from the "Update Subscription" form. It just returns null (in the instance of a free plan), and I'm not sure where to start looking to fix that.

EventFellows's avatar

You might want to try it via the $user->currentPlan()

There is some 'not so intuitive' things happening in spark due to the fact that spark is set up in a way that when a user cancels his plan he does not have that plan anymore but can still use it until the end of the payment cycle. That said, taking current_billing_plan column and $user->currentPlan() can give you different result in some cases (like a canceled but still valid subscription)

Please or to participate in this conversation.