You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 07:19:53