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

Stripe订阅场景下避免重复添加同一张支付卡的技术咨询

解决Stripe订阅中卡片重复添加的问题

问题根源

你遇到的卡片重复添加,是因为两个操作都在向客户关联同一张卡片:

  1. 手动调用stripe.PaymentMethod.attach提前关联卡片
  2. 创建订阅时设置了payment_settings={'save_default_payment_method': 'on_subscription'},支付确认后Stripe会自动将该卡片关联到客户并设为默认支付方式

而你误以为移除手动attach会导致无法生成客户端密钥,实际上客户端密钥来自订阅生成的Payment Intent,和提前关联卡片无关。

解决方案

1. 移除手动关联卡片的步骤

直接删掉第一步中stripe.PaymentMethod.attach和修改客户默认支付方式的代码,不需要提前将卡片关联到客户。

2. 调整订阅创建逻辑

保持订阅创建的核心配置,让Stripe在支付确认后自动处理卡片关联:

stripe_customer = stripe.Customer.retrieve(customer.stripe_customer_id)
stripe_subscription_list = stripe.Subscription.list(customer=customer.stripe_customer_id)
stripe_subscription_list_len = len(stripe_subscription_list.data)
stripe_subscription = None
if stripe_subscription_list_len != 0:
    stripe_subscription = stripe.Subscription.retrieve(stripe_subscription_list.data[0].id)

if ((stripe_subscription_list_len == 0) or (stripe_subscription_list_len == 1)) and \
    (selected_product.plan == 0 and customer.product.plan != selected_product.plan) or \
    (selected_product.plan > 0 and customer.product.plan != selected_product.plan):
    logging.info(f"SubscriptionCreate post Subscription Modify.")
    logging.info(f"SubscriptionCreate customer.product.plan : {customer.product.plan}")
    logging.info(f"SubscriptionCreate selected_product.plan : {selected_product.plan}")

    # 删除旧订阅(如果存在)
    if stripe_subscription:
        stripe.Subscription.delete(stripe_subscription.id)

    # 创建新订阅,依赖Stripe自动处理卡片关联
    new_subscription = stripe.Subscription.create(
        customer=customer.stripe_customer_id,
        items=[{"price": stripe_product.stripe_plan_id},],
        payment_behavior='default_incomplete',
        payment_settings={'save_default_payment_method': 'on_subscription'},
        expand=['latest_invoice.payment_intent'],
    )
    
    if new_subscription:
        customer.product = stripe_product
        customer.active = (customer.product.plan == 0)
        customer.clientsecret = new_subscription.latest_invoice.payment_intent.client_secret
        customer.stripe_subscription_id = new_subscription.id
        customer.save()
        logging.info(f"stripe_subscription_list new_subscription clientsecret : {customer.clientsecret}")

3. 前端支付确认逻辑保持不变

前端仍用订阅返回的客户端密钥调用stripe.confirmCardPayment,支付成功后Stripe会自动将卡片关联到客户并设为默认:

stripe.confirmCardPayment(resultState.data.clientsecret, {
  payment_method: {
    card: info.card_element,
    billing_details: {
      name: "Name Surname",
    },
  }
}).then((result) => {
  if (result.error) {
    // 处理支付错误
  } else {
    // 支付成功,订阅自动激活
  }
});

关键说明

  • payment_behavior='default_incomplete':创建订阅时生成未完成的Payment Intent,确保能返回客户端密钥给前端确认支付
  • payment_settings={'save_default_payment_method': 'on_subscription'}:支付成功后自动将卡片关联到客户,同时设为默认支付方式,用于后续订阅扣费
  • 这种方式既避免了卡片重复添加,又保证客户端密钥正常生成,完全符合Stripe的最佳实践

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 04:42:58