laravel / cashier-mollie

MIT License
375 stars 63 forks source link

$user->subscription('example-1')->cancel(); does not work #198

Closed rabol closed 4 years ago

rabol commented 4 years ago

The read me say this:

$user->subscription('main')->cancel();

how ever it does not seems to work

I have the 'example-1 plan in the configuration

$user = Auth::user(); $user->subscription('example-1')->cancel();

another example:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class CancelSubscriptionController extends Controller
{
    public function __invoke(string $plan)
    {
        $user = Auth::user();
        $user->subscription($plan)->cancel();
    }
}

the result is the same:

Call to a member function cancel() on null

looping over all user subscriptions seems to work

e.g.

foreach ( auth()->user()->subscriptions()->get() as $subscription) $subscription->cancel();

rabol commented 4 years ago

for this to work, one have to specify the plan description as the db contains the 'plan description in the name' and the plan in the plan column

->first(function ($value) use ($subscription) { return $value->name === $subscription; }

mmachatschek commented 4 years ago

It seems that you pass the cashier plan name from the config to the controller instead of the actual subscription name that you set upon creating the subscription.

The error Call to a member function cancel() on null happens, because the $user->subscription($plan) provided doesn't exist.

e.g. if you create the subscription:

$subscription = $user->newSubscription('main', 'example-1')->create();

The subscription would have the name main and not the name example-1.

In order to get the correct subscription you call:

$user->subscription('main')->cancel();
rabol commented 4 years ago

Maybe the documentation should be updated

I actually use a copy of this:

namespace App\Http\Controllers;

use Laravel\Cashier\SubscriptionBuilder\RedirectToCheckoutResponse;
use Illuminate\Support\Facades\Auth;

class CreateSubscriptionController extends Controller
{
    /**
     * @param string $plan
     * @return \Illuminate\Http\RedirectResponse
     */
    public function __invoke(string $plan)
    {
        $user = Auth::user();

        $name = ucfirst($plan) . ' membership';

        if(!$user->subscribed($name, $plan)) {

            $result = $user->newSubscription($name, $plan)->create();

            if(is_a($result, RedirectToCheckoutResponse::class)) {
                return $result; // Redirect to Mollie checkout
            }

            return back()->with('status', 'Welcome to the ' . $plan . ' plan');
        }

        return back()->with('status', 'You are already on the ' . $plan . ' plan');
    }
}

let's say that the controller is invoked with 'main' as parameter, then you will have the situation that I described.

because the subscription name will be 'Main' and not 'main' so when one later use 'main' to cancel it cannot be found because the subscription name in the db is 'Main'