I can't get a subscription to work. I always have the same error. I use Laravel 5.8 and Cashier 7. I detail my code and my problem.
This is the error
Symfony \ Component \ Debug \ Exception \ FatalThrowableError (E_ERROR)
Call to a member function create() on null
This is the POST DATA
POST Data
_token "5z6mnrUi64GcIy0EZzHVlDgw7EDBH1DqltVS0bJS"
restaurant_id "11"
stripeToken "tok_1HjJgFDpQQHNsFmdAKgw2ST2"
stripeTokenType "card"
stripeEmail "admin@demo.com"
The error seems to be in the file "\ vendor \ laravel \ cashier \ src \ SubscriptionBuilder.php" on line 204 "$ subscription = $ customer-> subscriptions-> create ($ this-> buildPayload ());"
File .env
STRIPE_KEY=Here I keep my keys
STRIPE_SECRET=Here I keep my keys
File config/services.php
I use a different model called Restaurant, instead of using the default User model. I have also tried the user model by default and the problem is the same.
'stripe' => [
'model' => App\Models\Restaurant::class,
'key' => env('STRIPE_KEY'),
'secret' => env('STRIPE_SECRET')
],
File App\Models\Restaurant.php
I implement and use the Billable class.
class Restaurant extends Model implements HasMedia
{
use Billable;
use HasMediaTrait {
getFirstMediaUrl as protected getFirstMediaUrlTrait;
}
public $table = 'restaurants';
...
File Database\Migrations\add_stripe_to_restaurants_table.php
public function up()
{
Schema::table('restaurants', function (Blueprint $table) {
$table->string('stripe_id')->nullable();
$table->string('card_brand')->nullable();
$table->string('card_last_four')->nullable();
$table->timestamp('trial_ends_at')->nullable();
});
}
File Database\Migrations\create_subscriptions_table.php
public function up()
{
Schema::create('subscriptions', function (Blueprint $table) {
$table->increments('id');
$table->integer('restaurant_id');
$table->string('name');
$table->string('stripe_id');
$table->string('stripe_plan');
$table->integer('quantity');
$table->timestamp('trial_ends_at')->nullable();
$table->timestamp('ends_at')->nullable();
$table->timestamps();
});
}
File routes\web.php
Route::post('process-subscription', 'SubscriptionController@process_subscription');
File resouerces\views\restaurants\edit.blade.php
<form id="silverPlan" action="{{ url('process-subscription') }}" method="POST">
{{ csrf_field() }}
<script
src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="{{ config('services.stripe.key') }}"
data-amount="990"
data-name="{!! trans('lang.subscription') !!}"
data-description="{!! trans('lang.silver_plan') !!}"
data-image="https://stripe.com/img/documentation/checkout/marketplace.png"
data-locale="{!! auth()->user()->language !!}"
data-currency="eur"
data-label="eeeeeee"
data-panel-label="aaaaaaa"
data-email="{{auth()->check()?auth()->user()->email:null}}">
</script>
</form>
File app\controllers\SubscriptionController.php
The "payment" method works perfectly, I can make individual payments fine. But the "process_subscription" method is where the problem is.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Stripe\Stripe;
use Stripe\Customer;
use Stripe\Charge;
use App\Models\Restaurant;
class SubscriptionController extends Controller
{
public function payment(Request $request)
{
try {
Stripe::setApiKey(config('services.stripe.secret'));
$customer = Customer::create(array(
'email' => $request->stripeEmail,
'source' => $request->stripeToken
));
$charge = Charge::create(array(
'customer' => $customer->id,
'amount' => 1990,
'currency' => 'eur'
));
return 'Cargo exitoso!';
} catch (\Exception $ex) {
return $ex->getMessage();
}
}
public function process_subscription(Request $request)
{
try {
Stripe::setApiKey(config('services.stripe.secret'));
$user = Restaurant::find(11);
$user->newSubscription('main', 'price_1Hj9QLDpQQHNsFmdASQGIYPB')->create($request->stripeToken);
return 'Suscripción exitosa! Acabas de suscribirte al Plan Plata';
} catch (\Exception $ex) {
return $ex->getMessage();
}
}
}