Laravel站点集成Stripe订阅未同步Stripe端自动取消的订阅状态如何修复
修复方案
你遇到的问题是未监听Stripe端触发的订阅状态变更事件,只要配置Stripe Webhook即可自动同步订阅状态,Laravel Cashier已经内置了相关事件的处理逻辑,无需大量二次开发。
1. 配置Stripe Webhook
首先进入Stripe后台的Webhook管理页,添加站点的Webhook接收地址,默认地址为https://你的域名/stripe/webhook,并勾选以下需要监听的事件:
customer.subscription.updated订阅信息更新时触发customer.subscription.deleted订阅被取消时触发invoice.payment_failed账单支付失败时触发
配置完成后复制Stripe生成的Webhook签名密钥,添加到站点.env配置文件中:
STRIPE_WEBHOOK_SECRET=你复制的签名密钥
2. 配置站点路由和中间件
首先将Webhook路由添加到CSRF校验排除列表,编辑app/Http/Middleware/VerifyCsrfToken.php:
protected $except = [ '/stripe/webhook', ];
如果你还没有注册Webhook路由,在routes/web.php中添加以下代码:
use Laravel\Cashier\Http\Controllers\WebhookController; Route::post('/stripe/webhook', [WebhookController::class, 'handleWebhook']);
配置完成后,Cashier会自动处理Stripe推送的订阅变更事件,当Stripe端因为支付失败自动取消订阅时,会自动更新数据库subscriptions表的ends_at字段,你现有的订阅校验逻辑无需修改即可正常生效。
3. 兜底同步方案(可选)
为了避免网络异常导致Webhook事件丢失的情况,可以添加定时任务每天同步一次活跃订阅的状态,编辑app/Console/Kernel.php,在schedule方法中添加以下代码:
$schedule->call(function () { // 遍历所有未取消的订阅 \Laravel\Cashier\Subscription::whereNull('ends_at') ->each(function ($subscription) { try { $stripeSubscription = $subscription->asStripeSubscription(); // Stripe端订阅非活跃状态则标记为已取消 if (!in_array($stripeSubscription->status, ['active', 'trialing'])) { $subscription->markAsCanceled(); } } catch (\Exception $e) { // 订阅在Stripe端不存在直接标记为取消 $subscription->markAsCanceled(); } }); })->daily();
内容的提问来源于stack exchange,提问作者Jake Scervino
相关产品推荐
相关产品推荐

