Laravel Cashier 出现 Call to a member function checkout() on null 结算报错
问题原因
- Billable模型实例未持久化到本地数据库:你代码中
$user = new App\Competitor();初始化实例后,仅调用了createAsStripeCustomer生成Stripe侧客户,没有将包含stripe_id的模型数据写入本地数据库。Cashier::findBillable($id)的核心逻辑是先查询本地Billable模型表中stripe_id匹配的记录,本地无对应记录时会直接返回null,和Stripe侧是否存在该客户无关。 - Cashier默认Billable模型配置不匹配:Laravel Cashier默认关联的账单模型是
App\User(高版本为App\Models\User),你使用自定义的Competitor作为Billable模型,未修改Cashier配置的情况下,findBillable会默认查询users表而非competitors表,自然找不到对应记录。
解决方案
- 优先采用简化写法:你的场景完全不需要调用
Cashier::findBillable,直接使用已加载Billable trait的$user实例调用checkout即可,绕开findBillable的查询逻辑,同时记得先将Competitor实例持久化到数据库,修改后代码如下:
use Laravel\Cashier\Cashier; // 直接用create方法生成持久化到数据库的实例,填充业务必填字段 $user = App\Competitor::create([ 'name' => $request->name, 'email' => $request->email, 'phone' => $request->phone, // 补充其他你业务要求的必填字段,比如ip_address、selected_event等 ]); // createAsStripeCustomer会自动读取模型的name/email/phone字段,不需要手动传参 $stripeCustomer = $user->createAsStripeCustomer(); // 直接用现有$user实例调用checkout即可 return $user->checkout(['price_foobarfoobar' => 1], [ 'success_url' => 'https://staging.domain.com/thank-you', 'cancel_url' => 'https://staging.domain.com/sign-up', ]);
- 如果你确实需要使用
Cashier::findBillable方法,需要修改config/services.php中的Stripe配置,指定默认Billable模型:
// config/services.php 下的stripe配置块新增model参数 'stripe' => [ 'key' => env('STRIPE_KEY'), 'secret' => env('STRIPE_SECRET'), 'model' => App\Competitor::class, ],
内容的提问来源于stack exchange,提问作者kryz
相关产品推荐
相关产品推荐

