Laravel Cashier自定义模型下取消订阅报stripe()空对象调用错误
Laravel Cashier 自定义模型对接时取消订阅报错修复
问题现象
在Laravel项目中使用自定义Profile模型对接Laravel Cashier实现订阅功能,订阅创建流程调试正常,执行取消订阅操作时抛出异常,无法完成取消逻辑。
相关代码与报错信息
业务调用代码
$profile = Profile::where('userid', $userid)->first(); //print_r($profile);exit; $cancel = $profile->subscription('DailyPlan')->cancel();
错误信息
Call to a member function stripe() on null
报错指向的Cashier内置方法
public function updateStripeSubscription(array $options = []) { // print_r($options);exit; // print_r($this->stripe_id);exit; return $this->owner->stripe()->subscriptions->update( $this->stripe_id, $options ); }
问题根因
报错原因是Subscription实例的$this->owner属性返回null:Cashier默认的Subscription模型关联的账单所有者(Billable)是框架自带的User模型,使用自定义Profile模型作为Billable主体时,没有修改Subscription的关联配置,导致关联查询所有者时拿不到对应Profile实例,后续调用stripe()方法直接触发空对象错误。
修复步骤
- 自定义Subscription模型继承Cashier原生Subscription类,重写owner关联方法,绑定到你的Profile模型:
<?php namespace App\Models; use Laravel\Cashier\Subscription as CashierSubscription; class Subscription extends CashierSubscription { public function owner() { // 外键字段根据你实际的表结构调整,默认是billable_id关联账单主体主键 return $this->belongsTo(Profile::class, 'billable_id'); } }
- 在服务启动阶段注册自定义模型配置,在
App\Providers\AppServiceProvider的boot方法中添加以下配置:
<?php namespace App\Providers; use App\Models\Profile; use App\Models\Subscription; use Illuminate\Support\ServiceProvider; use Laravel\Cashier\Cashier; class AppServiceProvider extends ServiceProvider { public function boot() { // 指定自定义的Billable客户模型 Cashier::useCustomerModel(Profile::class); // 指定自定义的Subscription模型 Cashier::useSubscriptionModel(Subscription::class); } }
- 校验历史数据:检查
subscriptions表的billable_type字段,确认存储值为Profile模型的全限定类名(即App\Models\Profile),如果之前创建订阅时该字段存的是User模型类名,批量修正历史数据即可,否则关联查询依然会返回null。
内容的提问来源于stack exchange,提问作者Karthick Kumar
相关产品推荐
相关产品推荐

