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

Geser's avatar
Level 2

App\User::createAsStripeCustomer() should not be called statically

Hi,

I'm new to Laravel and am finding it an awesome tech and Laracasts an excellent resource that is generally excellent and has made getting going very rewarding.

I've watched the Laracast series about Laravel 6, and also the one about the new Cashier module. I've also played with an example of a Laravel 5/Cashier site and have is all set up and working, but I want to use Laravel 6, partly because the new error handling/reporting is very informative.

I'm having trouble getting going with Cashier in Laravel 6. As a first step, I'm trying to modify the template code for a laravel/ui vue --auth with laravel/cashier so that when a new user registers, they are automatically registered as a Strip user with User::createAsStripeCustomer(). To do this, I replaced User::create() (in RegisterController::create()) with User::createAsStripCustomer() but I get the following error:

ErrorException
Non-static method App\User::createAsStripeCustomer() should not be called statically 

So I guess that the Billable trait has the static method, and that I'm trying to call it from a non-static method? Can anyone suggest a neat/simple way to fix this?

Failing a fix for where/how to register a new user as a Stripe customer with Cashier in the template code created by composer require laravel/ui and php artisan ui vue --auth, is there a more up-to-date tutorial that walks through the basic usage of Cashier? (The existing Laracast about Cashier/Stripe uses Strip in a seemingly out-dated way).

0 likes
4 replies
Sinnbeck's avatar

The documentation states that it should be called dynamically. https://laravel.com/docs/6.x/billing#creating-customers

$user->createAsStripeCustomer();

I haven't used it myself, but I would image it expects that you create the actual user locally first, then load that customer, and then run that method on the user instance.

Geser's avatar
Level 2

I guess it would be clearer with the actual code...

This is the error-causing code:

    protected function create(array $data)
    {
        return User::createAsStripeCustomer([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => Hash::make($data['password']),
        ]);
    }

The above usage seems a logical usage to me. Since you shouldn't call create() on an instantiated object (create should construct one).

Which I guess should be something like:

    protected function create(array $data)
    {
        return User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => Hash::make($data['password']),
        ])->someMemberMethodToInitUserInStripe(); // <-- *** from Billable
    }

But... I've moved past this issue. I've opted for a SubscribeController and things are working.

Sinnbeck's avatar

I still believe that you would actually need to create them in your local database first.

    protected function create(array $data)
    {
return User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => Hash::make($data['password']),
        ])->createAsStripeCustomer()
    }
Geser's avatar
Level 2

Success as far as Stripe user creation with (RegisterController.php):

    protected function create(array $data)
    {
        $user = User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => Hash::make($data['password']),
        ]);

        $user->createAsStripeCustomer(); // TODO: try catch and spawn Job to create the Strip user on-error

        return $user;
    }

So now I'm trying to get a payment method set up with Stripe Intents (routes/web.php):

Route::get('/addpayment', 'HomeController@addpayment', function (Request $request){
    // grab the user
    $user = $request->user();
    return view('addpayment', [
        'intent' => $user->createSetupIntent()
    ]);
})->name('addpayment');

But I'm getting a The POST method is not supported for this route. Supported methods: GET, HEAD. error because of the route. I assume that the Strip Intent form should still POST and not HEAD?

Please or to participate in this conversation.