如何通过Stripe限制客户3个月内不可取消月度订阅?
实现Stripe月度订阅前3个月不可取消的方案
你可以通过两种核心方案实现这个需求,下面是具体步骤和代码示例:
方案一:利用Stripe原生最低承诺周期(推荐)
Stripe的价格对象支持设置minimum_commitment,强制客户完成指定周期的订阅后才能取消。这种方式是Stripe原生支持,无需额外自定义逻辑,稳定性最高。
1. 创建带最低承诺的月度价格
在创建订阅对应的价格时,指定客户必须订阅至少3个月:
// 创建月度价格,要求至少订阅3个月 const price = await stripe.prices.create({ unit_amount: 1000, // 10美元(单位:分) currency: 'usd', recurring: { interval: 'month', interval_count: 1, }, product: 'prod_xxxxxx', // 你的产品ID minimum_commitment: { type: 'months', value: 3, }, });
2. 配置客户门户权限
在创建客户门户会话时,结合最低承诺设置,让Stripe自动管控取消权限:
const session = await stripe.billingPortal.sessions.create({ customer: customer.stripeCustomerId, return_url: 'https://my-website.com', features: { subscription_cancel: { enabled: true, // Stripe会自动判断订阅是否满足最低承诺,未满足时隐藏取消选项 cancellation_policy: 'at_period_end', }, }, });
当订阅未满足3个月要求时,客户门户会自动隐藏取消按钮,直接通过API调用取消也会被Stripe拒绝。
方案二:自定义权限控制+Webhook验证(灵活场景)
如果需要针对特定客户群体设置差异化限制,可以通过客户门户权限配置+Webhook拦截实现:
1. 关闭客户门户默认取消功能
先在客户门户会话中禁用取消选项,避免客户直接操作:
const session = await stripe.billingPortal.sessions.create({ customer: customer.stripeCustomerId, return_url: 'https://my-website.com', features: { subscription_cancel: { enabled: false, // 关闭门户内的取消按钮 }, }, });
2. 通过Webhook拦截非法取消请求
监听Stripe的customer.subscription.deleted事件,验证订阅时长,未满足3个月则恢复订阅:
// Stripe Webhook处理示例 app.post('/stripe-webhook', express.raw({type: 'application/json'}), async (req, res) => { const sig = req.headers['stripe-signature']; let event; try { event = stripe.webhooks.constructEvent( req.body, sig, '你的Webhook密钥' ); } catch (err) { return res.status(400).send(`Webhook Error: ${err.message}`); } if (event.type === 'customer.subscription.deleted') { const subscription = event.data.object; // 计算订阅创建时长(近似月数) const createdDate = new Date(subscription.created * 1000); const now = new Date(); const monthsDiff = (now.getFullYear() - createdDate.getFullYear()) * 12 + now.getMonth() - createdDate.getMonth(); // 未满3个月则恢复订阅 if (monthsDiff < 3 && !subscription.cancel_at_period_end) { await stripe.subscriptions.update(subscription.id, { cancel_at_period_end: false, status: 'active', }); // 可额外给客户发送通知说明限制规则 } } res.json({received: true}); });
补充:自定义取消入口(可选)
如果需要在自有网站给符合条件的客户开放取消入口,可先查询订阅时长再判断:
// 查询客户活跃订阅 const subscriptions = await stripe.subscriptions.list({ customer: customer.stripeCustomerId, status: 'active', }); // 判断是否满足取消条件 const canCancel = subscriptions.data.some(sub => { const createdDate = new Date(sub.created * 1000); const now = new Date(); const monthsDiff = (now.getFullYear() - createdDate.getFullYear()) * 12 + now.getMonth() - createdDate.getMonth(); return monthsDiff >= 3; }); // 根据canCancel的值决定是否显示取消按钮
内容的提问来源于stack exchange,提问作者javed iqbal
相关产品推荐
相关产品推荐

