直接运行 composer require laravel/cashier 即可安装,Cashier 是运行时依赖;需手动发布迁移和配置、确保 User 实现 Billable 并含 stripe_id 字段、正确配置 Stripe 密钥及 Webhook 豁免与签名。

Composer 安装 laravel/cashier 的正确命令
直接运行 composer require laravel/cashier 就够了,不需要加版本号或 --dev。Cashier 是运行时依赖,不是开发工具,放生产环境里才起作用。
常见错误是手动改 composer.json 后忘记 composer install,或者用了 require-dev 导致上线后 Class 'Laravel\Cashier\Cashier' not found。
- 确保当前目录是 Laravel 项目根目录(有
composer.json和artisan) - 如果项目已启用自动加载缓存,装完后建议跑一次
composer dump-autoload - Laravel 10+ 默认用 Stripe v12,Cashier v14 起强制要求 Stripe PHP SDK v12+;若项目里已有旧版
stripe/stripe-php,Composer 会报冲突,得先composer remove stripe/stripe-php再装 Cashier
Laravel 10/11 中发布 Cashier 迁移和配置
Cashier 不自动发布迁移,也不写配置文件——你得自己动手。漏掉这步,php artisan migrate 会找不到 subscriptions 表,后续调用 user->subscribe() 直接抛 SQLSTATE[42S02]: Base table or view not found。
执行命令:php artisan vendor:publish --tag="cashier-migrations"(生成迁移)和 php artisan vendor:publish --tag="cashier-config"(生成 config/cashier.php)。
- 迁移发布后别急着
migrate,先检查生成的文件是否在database/migrations下,有时因权限问题会写到错路径 -
config/cashier.php里关键项是'model' => App\Models\User::class,如果你的用户模型不在默认路径,必须手动改这里,否则订阅关系绑定失败 - Stripe key 必须设在
.env里:STRIPE_KEY=sk_test_...和STRIPE_SECRET=sk_test_...,Cashier 不读config/cashier.php里的 key
初始化 Stripe 客户和订阅前必须做的两件事
调 $user->createAsStripeCustomer() 或 $user->newSubscription(...)->create(...) 前,必须确保 User 模型实现了 Billable trait,且数据库字段 stripe_id 已存在(由 Cashier 迁移提供)。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
典型翻车现场:用户表没 stripe_id 字段,但代码照跑,结果 createAsStripeCustomer() 返回 null,后续所有订阅操作静默失败,日志里只有一行 Stripe\Exception\AuthenticationException(其实是空 stripe_id 导致 API 请求头缺失)。
- 确认
User类里有use Laravel\Cashier\Billable;和use Billable; - 检查数据库中
users表是否含stripe_id(varchar 255,默认可空),没有就补个迁移:$table->string('stripe_id')->nullable()->index() - 测试时别用
STRIPE_KEY=pk_test_...(Publishable Key),必须用 Secret Key(sk_test_...),否则Cashier::swap()等后台操作全 401
Webhook 验证失败的三个高频原因
stripe/webhook 路由返回 400 或 “Signature verification failed”,基本不是代码逻辑问题,而是配置链断了。
最常被忽略的是:Laravel 的 VerifyCsrfToken 中间件默认拦截所有非 GET 请求,而 Stripe webhook 是 POST,必须把 /webhook 加进豁免列表;另外,Webhook secret 必须和 Stripe Dashboard 里复制的一模一样(含 whsec_ 前缀),少一个字符就验不过。
- 在
app/Http/Middleware/VerifyCsrfToken.php的$except数组里加'webhook'或'stripe/webhook' -
STRIPE_WEBHOOK_SECRET=whsec_...必须写进.env,不能只写在config/cashier.php里 - 本地调试用
stripe-cli时,确保启动命令带--forward-to http://localhost:8000/stripe/webhook,且 Laravel APP_URL 设为http://localhost:8000(https 会导致验证失败)
Webhook 是整个支付闭环里最脆弱的一环,签名、路由、中间件、环境变量、Secret 值,五者缺一不可。少配一个,退款、取消订阅这些事件就永远进不来。

















