如何使用Laravel Cashier先一次性收费,之后按月向客户扣费?
Laravel Cashier 实现预付+后续月付方案
你的初始思路(先一次性收费再设3个月试用订阅)不推荐——因为Stripe/Cashier里的“试用”本质是免费期,和用户已经支付的10美元预付逻辑冲突,会导致订阅状态混乱,后续账单查询、退款处理都会变麻烦。下面给你两种更合理的实现方案:
方案一:一次性收费+延迟激活的定期订阅
这是最直接的方式,逻辑清晰,不需要额外的订阅切换操作:
- 先收取10美元一次性预付费用:
// 金额单位为分,10美元对应1000分 $user->charge(1000, $paymentMethod); - 创建月付订阅,但设置3个月后才开始计费:
这里的$user->newSubscription('main', 'your-monthly-plan-id') ->trialUntil(now()->addMonths(3)) ->create($paymentMethod);trialUntil会让订阅在3个月后自动激活并开始按月扣费,Cashier会自动处理后续的账单周期,用户的订阅状态全程连贯。
方案二:预付费订阅计划+自动切换月付
如果希望完全通过订阅计划管理(更贴合Stripe的原生逻辑),可以这么做:
- 在Stripe后台创建两个计划:
- 一个3个月预付费计划:价格设为10美元,计费周期3个月,设置为到期不自动续费。
- 一个月付计划:设置你需要的月费金额,按月自动续费。
- 用户首次加入时,订阅3个月预付费计划:
$user->newSubscription('main', 'your-3month-prepaid-plan-id') ->create($paymentMethod); - 监听Stripe的
customer.subscription.updated或customer.subscription.deleted事件,当预付费订阅到期后,自动为用户切换到月付订阅:
这种方式的好处是所有费用都通过订阅流程管理,账单记录更清晰,但需要配置Webhook并处理订阅切换的逻辑。// 在Stripe Webhook事件监听器中 $stripeSubscription = $event->data->object; $user = User::where('stripe_id', $stripeSubscription->customer)->first(); if ($user && $stripeSubscription->plan->id === 'your-3month-prepaid-plan-id') { // 使用用户默认支付方式创建月付订阅 $user->newSubscription('main', 'your-monthly-plan-id') ->create($user->defaultPaymentMethod()->id); }
注意事项
- 务必配置Stripe Webhook,处理订阅到期、扣费失败等事件,避免出现用户服务中断或扣费异常的情况。
- 一次性收费后要做好订单记录,方便后续用户查询和退款操作。
- 切换订阅时要检查用户的支付方式是否有效,避免后续扣费失败。
内容的提问来源于stack exchange,提问作者Musawer Shah
相关产品推荐
相关产品推荐

