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

felipepena's avatar

How to automatically adjust Laravel Spark/Cashier subscription pricing based on seat count?

I’m working on a Laravel project that uses Laravel Spark with Cashier for subscription billing.

What I want to achieve is this:

  • Users subscribe to the app.
  • The system charges them based on the number of seats they have.
  • If the seat count changes, the billing amount should automatically adjust.

The issue is that Spark/Cashier seems to require the user to manually switch plans in the billing portal to change pricing. I don’t want that. Instead, I’d like the pricing to update automatically when the seat count changes—without requiring the user to do anything in the portal.

My questions are:

  • Can this be done without defining multiple fixed plans in Spark?
  • Or is the right approach to define multiple plans but programmatically move the user to the right plan when their seat count changes?
  • Is there a best practice for handling this scenario in Spark/Cashier?

Any guidance, code examples, or direction on how to implement this would be appreciated.

0 likes
3 replies
LaryAI's avatar
Level 58

Absolutely, this is a common scenario for SaaS apps with per-seat pricing. Laravel Spark (and underlying Laravel Cashier) supports per-seat billing, but you need to handle seat count changes in your application logic to ensure the subscription quantity (which represents seats) is kept in sync with your actual seat count.

Answers to your questions:

  1. Can this be done without defining multiple fixed plans in Spark?
    Yes. You do not need to define multiple plans for different seat counts. Instead, you use a single plan with a per-seat price, and update the subscription "quantity" to match the seat count.

  2. Or is the right approach to define multiple plans but programmatically move the user to the right plan when their seat count changes?
    No, that's not necessary for per-seat billing. Use a single plan and adjust the quantity.

  3. Is there a best practice for handling this scenario in Spark/Cashier?
    Yes: update the subscription quantity whenever the seat count changes. Cashier will automatically handle proration and billing adjustments.


How to Implement Automatic Seat-Based Billing

Step 1: Set Up a Per-Seat Plan in Stripe

  • In Stripe, create a plan/product with a per-seat price (e.g., $10 per seat per month).
  • In Spark, reference this plan in your configuration.

Step 2: Update Subscription Quantity When Seat Count Changes

Whenever the user's seat count changes (e.g., they add/remove a team member), update the subscription's quantity:

// Assume $user is the billable model (e.g., Team or User)
// $newSeatCount is the updated number of seats

$user->subscription('default')->updateQuantity($newSeatCount);
  • This will update the Stripe subscription quantity and automatically adjust the billing amount.
  • Cashier will handle proration if the seat count changes mid-cycle.

Step 3: Automate the Update

You should call updateQuantity() whenever your seat count changes. For example, if seats are tied to team members:

public function addTeamMember(Request $request, Team $team)
{
    // ... logic to add member ...
    $team->subscription('default')->updateQuantity($team->members()->count());
}

And similarly when removing a member.


Summary

  • Do not create multiple plans for different seat counts.
  • Use a single per-seat plan and update the subscription quantity to match the actual seat count.
  • Call $subscription->updateQuantity($seatCount) whenever the seat count changes.

References:

Let me know if you need a more detailed code example or have a specific use case!

felipepena's avatar

Ok, that sounds good.

But then how can I define the tiered pricing on Stripe side?

mileswebhosting's avatar

you can utilize per-seat billing, Define Per-Seat Billing in SparkServiceProvider

Please or to participate in this conversation.