
在 stripe 中,不能通过 `cancel()` 方法设置 `cancel_at_period_end` 参数来延迟取消订阅;必须使用 `update()` 方法更新订阅对象,将 `cancel_at_period_end` 设为 `true` 才能实现“到期自动终止”。
Stripe 的订阅取消机制分为两种行为:立即取消(immediate cancellation)和周期结束时取消(cancellation at period end)。关键在于:cancel() 接口仅支持立即终止,并忽略所有如 cancel_at_period_end 或 invoice_now 等非标准参数(这些参数在该端点中不被接受,也不会生效)。
要实现“订阅保留至当前计费周期结束、之后不再续订”的效果,正确做法是调用 subscriptions->update() 方法,仅传入 'cancel_at_period_end' => true:
try {
$subscription = $stripe->subscriptions->update(
$subscription_id,
[
'cancel_at_period_end' => true
]
);
// 可选:检查响应确认状态
if ($subscription->cancel_at_period_end) {
echo "订阅已成功设置为周期结束时取消。";
}
} catch (\Stripe\Exception\ApiErrorException $e) {
error_log("Stripe 更新订阅失败: " . $e->getMessage());
throw $e;
}✅ 注意事项:
- cancel_at_period_end 是布尔值,设为 true 后,Stripe 会自动将 cancel_at 字段更新为当前周期的 current_period_end 时间戳;
- 订阅在到期前仍保持 active 状态,用户可继续享受服务,且不会触发额外账单;
- 若后续需提前立即取消,可再次调用 cancel()(此时将无视 cancel_at_period_end,强制终止);
- 不要混用 invoice_now 和 cancel_at_period_end —— 前者仅适用于立即取消并开票的场景,与延期取消逻辑冲突。
? 小贴士:可通过 $subscription->status 和 $subscription->cancel_at_period_end 字段实时校验订阅状态,确保业务逻辑与 Stripe 实际行为一致。









