Laravel 6与Laravel 10应用共享Cashier(Stripe)的字段兼容问题求解
解决跨Laravel版本Cashier字段差异的方案
针对Laravel 6(旧版Cashier)和Laravel 10(新版Cashier)共用订阅数据库的字段差异问题,以下是几个落地性强的解决思路:
1. 统一数据库表结构并做字段兼容
首先梳理两个版本Cashier的订阅表(subscriptions)核心字段差异,比如新版可能新增stripe_price、currency,旧版用stripe_plan存储价格ID,字段命名不一致。
- 以新版表结构为基准:给旧数据库新增所有新版要求的字段,允许为空或设置合理默认值(比如
currency默认usd)。 - 旧应用模型层兼容:在Laravel 6的
Subscription模型(建议自定义继承原Cashier模型,避免修改包源码)中添加字段映射的访问器/修改器:use Laravel\Cashier\Subscription as CashierSubscription; class Subscription extends CashierSubscription { // 把旧字段映射到新版需要的字段名 public function getStripePriceAttribute() { return $this->stripe_plan; } // 如果新版有必填字段,设置默认值 protected $attributes = [ 'currency' => 'usd', ]; }
2. 双应用使用自定义订阅模型隔离差异
两个应用都放弃使用Cashier自带的Subscription模型,改用自定义模型来做字段适配:
- Laravel 6侧:自定义模型将新版字段映射为旧版Cashier预期的字段名,确保旧代码逻辑无需修改。
- Laravel 10侧:自定义模型可以兼容旧字段(比如给
stripe_plan添加访问器,返回stripe_price的值),同时满足新版Cashier的要求。
示例:Laravel 6的自定义Subscription模型
use Laravel\Cashier\Subscription as CashierSubscription; class Subscription extends CashierSubscription { public function getStripePriceAttribute() { return $this->stripe_plan; } }
然后在User模型中指定关联的自定义模型:
public function subscriptions() { return $this->hasMany(Subscription::class)->orderBy('created_at', 'desc'); }
3. 用数据库视图做字段映射层
如果不想修改任何模型代码,可以给订阅表创建数据库视图,让两个应用看到的字段结构一致:
比如给Laravel 6应用创建视图,将新版字段名映射为旧版的名称:
CREATE VIEW subscriptions_compat AS SELECT id, user_id, name, stripe_id, stripe_price AS stripe_plan, stripe_status, quantity, trial_ends_at, ends_at, created_at, updated_at, currency, interval FROM subscriptions;
然后Laravel 6的Subscription模型指定表为subscriptions_compat即可,Laravel 10直接使用原表。
4. 逐步迁移用户到新版应用
如果长期维护双版本成本过高,建议分批迁移用户到Laravel 10应用:
- 先确保Laravel 10应用完全兼容旧订阅数据(比如处理旧字段的映射);
- 分批迁移用户,迁移时同步订阅状态,同时禁用Laravel 6的订阅操作入口;
- 全部迁移完成后,停用Laravel 6的订阅相关功能。
内容的提问来源于stack exchange,提问作者Jonathan Hyams
相关产品推荐
相关产品推荐

