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

netgeek88's avatar

Subscription::discount() undefined in Prod - Works Localhost

I am using Cashier for Stripe, and the Subscription class called App\Models\Subscription::discount(). In localhost/dev, this works just fine with zero issues. In Production, with the code being the same, I get a 500 error with the following error:

production.ERROR: Call to undefined method App\Models\Subscription::discount() {"userId":2,"exception":"[object] (BadMethodCallException(code: 0): Call to undefined method App\Models\Subscription::discount() at /var/www/blackdiamond/vendor/laravel/framework/src/Illuminate/Support/Traits/ForwardsCalls.php:71)
[stacktrace]

Here is the method in the SubscriptionController.php:

public function getSubscriptions()
    {
        $user = Auth::user();
        //$subscriptions = $user->subscriptions()->active()->get();
        $subscriptions = Subscription::where('user_id', '=', $user->id)->where('stripe_status', '=', 'active')->get();
//print($subscriptions);

        if (count($subscriptions) > 1) {
            $hasAddons = true;
        } else {
            $hasAddons = false;
        }

        $addons = [];
        $addon_prices = [];
        foreach ($subscriptions AS $key => $subscription) {
            if ($subscription->name == 'license') {
                $plan = Plan::where('plan_id', '=', $subscription->stripe_price)->first();
                $plan_price = Price::where('price_id', '=', $subscription->stripe_price)->first();
                $sub_stripe = Cashier::stripe()->subscriptions->retrieve($subscription->stripe_id);
                $plan_discount = ($sub_stripe->discount != null) ? $subscription->discount()->coupon() : false;
            } else {
                $addon_plan = Plan::where('plan_id', '=', $subscription->stripe_price)->first();
                $addons = Arr::add($addons, $key, array($addon_plan, 'subscription' => $subscription->stripe_id));
                $addon_price = Price::where('price_id', '=', $subscription->stripe_price)->first();
                $sub_stripe = Cashier::stripe()->subscriptions->retrieve($subscription->stripe_id);
                $discount = ($sub_stripe->discount != null) ? $subscription->discount()->coupon() : false;
                $addon_prices = Arr::add($addon_prices, $key, array($addon_price, 'discount' => $discount, 'subscription' => $subscription->stripe_id));
            }
        }
//return $addons;
        return view('stripe.view-subscriptions', [
            'subscriptions' => $subscriptions
            , 'hasAddons' => $hasAddons
            , 'plan' => $plan
            , 'addons' => $addons
            , 'plan_price' => $plan_price
            , 'addon_prices' => $addon_prices
            , 'plan_discount' => $plan_discount
        ]);
    }

    public function decreaseAddonQuantity($subscription_id)
    {
        $user = Auth::user();

        foreach ($user->subscriptions AS $sub) {
            if ($sub->stripe_id == $subscription_id)
            {
                $addon_subscription = $sub;
            }
        }

        switch ($addon_subscription->name) {
            case "addon-connection":
                $type = "Connections";
                break;
            case "addon-user":
                $type = "Users";
                break;
        }
//return $addon_subscription;

        return view ('stripe.decrease-addon-qty', ['addon_subscription' => $addon_subscription, 'type' => $type]);
    }
0 likes
11 replies
Snapey's avatar

where is your discount method? Lets see the model...

1 like
netgeek88's avatar

@Snapey This is my model, which works in localhost but not on production:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Subscription extends Model
{
    use HasFactory;
}

And this is the top of my SubscriptionController:

<?php

namespace App\Http\Controllers\Stripe;

use Carbon\Carbon;
use App\Models\Stripe\Plan;
use Illuminate\Support\Arr;
use App\Models\Stripe\Price;
use App\Models\Subscription;
use Illuminate\Http\Request;
use Laravel\Cashier\Cashier;
use App\Models\Stripe\Product;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;

class SubscriptionController extends Controller
{
1 like
tykus's avatar

@netgeek88 there is no discount method in your model as mentioned above. So, on this line, where $subscription is an instance of your model; it make no sense:

$plan_discount = ($sub_stripe->discount != null) 
    ? $subscription->discount()->coupon() // your Subscription model
    : false;

Were you expecting to use a Casher Subscription instance instead?

1 like
netgeek88's avatar

@tykus

Yes; But again, the same exact code works in localhost but not Production. Which doesn't make sense to me if it was something like what you're describing might be the issue.

1 like
tykus's avatar

@netgeek88 the code you have shared should not be working in either environment.

1 like
netgeek88's avatar

@tykus

Thus, my absolute confusion why it works in one and not the other. Any recommendations on something to try? Any reason why Laravel would work locally in some instances but in those same instances not work in production?

1 like
vincent15000's avatar
Level 63

@netgeek88 The discount() method is available for the subscriptions and for the customers. But if you create a custom subscription model, as mentioned in the documentation, you should extend the custom Subscription model from CashierSubscription and not from Model.

use Laravel\Cashier\Subscription as CashierSubscription;
 
class Subscription extends CashierSubscription
{
    // ...
}

https://laravel.com/docs/10.x/billing#using-custom-models

Why do you have a custom subscription model ? Have you created specific methods inside it ?

netgeek88's avatar

@vincent15000

I can try that, but it is unclear why the same code works in localhost and not production. Do you have any ideas as to why that might happen?

1 like
vincent15000's avatar

@netgeek88 Your code can't work, no matter if it's in local or in production.

What perhaps happens is that in local you don't really use this part of the code when you test the application.

netgeek88's avatar

@vincent15000

That fixed it. For anyone wondering, I was using Stripe and there was a 100% discount in production but no discount in Test Mode (localhost). When I added a 1% discount in Test Mode, localhost stopped working. I did as vincent15000 said, and it works in both localhost and production.

Thank you to everyone for the help.

1 like

Please or to participate in this conversation.