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

首次使用Stripe订阅功能的开发逻辑与实现问题咨询

Stripe订阅开发问题解答

首先纠正你现有代码里的几个接口认知错误:

  • stripe.PaymentIntent.retrieve 接口要求传入PaymentIntent的对象ID,不支持传入Customer ID查询,你当前传stripe_customer_id调用会直接返回参数错误
  • last_payment_error是单次PaymentIntent对象的属性,不存储用户维度的历史支付错误信息,也无法直接用来判断订阅是否过期
  • Customer对象本身不携带订阅状态、试用期、支付失败相关的关联信息,不能直接用来判断订阅有效性

各需求实现方案

1. 订阅状态/免费试用期校验

  • 直接调用stripe.Subscription.list接口,入参传入customer=self.stripe_customer_id拉取该用户名下所有订阅,不需要先查Customer对象
  • 遍历返回的订阅列表,只要存在订阅的status字段为active(正常生效)或trialing(免费试用期),即可判定为持有有效订阅
  • 过滤掉canceled(已取消)、incomplete_expired(未完成支付超时作废)、unpaid(多次扣款失败作废)状态的订阅,这些不属于有效范畴

2. 支付异常/订阅过期校验

  • 不要单独查询PaymentIntent找支付错误:订阅的最近一次扣款记录绑定在Subscription对象的latest_invoice字段上,拿到发票ID后调用stripe.Invoice.retrieve查询,只要Invoice的payment_error字段不为空,就说明最近一次扣款失败,常见原因就是银行卡余额不足、卡过期、风控拦截
  • 订阅过期直接看Subscription的status字段:如果状态为canceled/incomplete_expired/unpaid,说明订阅已经彻底失效;如果是past_due状态,属于扣款失败后的宽限期,Stripe还会按照配置的规则自动重试扣款,这个阶段可以保留用户访问权限,只提示用户更新支付方式即可,不需要直接判定为过期

3. 订阅扣款规则说明

  • 完全不需要自行配置Celery定时任务做周期扣款,Stripe订阅是全托管自动扣款模式:你创建订阅时配置好计费周期(支持月付、年付、自定义天数周期),Stripe会在每个计费周期到期日自动发起扣款、生成账单和发票,不需要手动调度
  • 自己写定时任务扣款不仅重复开发,还极易出现重复扣款、对账不一致、时区计算错误等问题,没有必要。你只需要配置Stripe Webhook监听订阅状态变更、扣款成功/失败事件,把状态同步到本地数据库即可,不需要主动轮询扣款。

修正后的参考代码

@property
def is_valid_subscribion(self):
    try:
        # 拉取用户名下所有订阅
        subscriptions = stripe.Subscription.list(
            customer=self.stripe_customer_id,
            status="all",
            limit=10
        )
    except Exception:
        return False, "You don't have a subscription."

    valid_sub = None
    for sub in subscriptions.auto_paging_iter():
        # 筛选出未彻底作废的订阅
        if sub.status in ["active", "trialing", "past_due"]:
            valid_sub = sub
            break
    
    if not valid_sub:
        return False, "Your subscription is expired please make sure your card is valid"
    
    # 校验最近一次支付是否存在错误
    latest_invoice = stripe.Invoice.retrieve(valid_sub.latest_invoice)
    if getattr(latest_invoice, 'payment_error', None) is not None:
        return False, "Your latest subscription payment failed, please check if your card has sufficient balance"
    
    if valid_sub.status == "trialing":
        return True, "You are currently in the free trial period"
    
    return True, "Valid subscription"

内容的提问来源于stack exchange,提问作者Ali Husham

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 23:42:27