Stripe v3 - SetupIntents 和订阅

Edu*_*pez 8 stripe-payments stripe-subscriptions

我正在尝试使用 SetupIntents 来验证和保存付款方式,然后使用它创建订阅以向客户收取所需金额(立即然后每月)。

这似乎工作正常:

  • 该卡已验证(如果需要,包括 SCA)
  • 付款方式已创建,默认附加到客户并启用以供将来使用,状态为 SUCEEDED。
  • 订阅已创建并使用上述付款方式

问题是,当提供的卡需要安全客户授权 (SCA) 时,Stripe 然后生成相应的发票和付款意图,但后者的状态为“requires_action”,即使正在使用正确的付款方式(为将来使用启用)并且已执行卡验证。

我认为使用 SetupIntents 的全部意义在于事先验证付款方式,然后能够向客户收费。

我的假设是否完全错误,或者这实际上是可能的,我可能只是遗漏了什么?

提前致谢

编辑:这是后端的订阅创建代码:

# Set the default payment method on the customer
      Stripe::Customer.update(
        stripe_customer_id,
        invoice_settings: {
          default_payment_method: @requested_source
        }
      )

subscription = Stripe::Subscription.create({
       "customer" => stripe_customer_id,
       "proration_behavior" => 'create_prorations',
       "items" => [
         [
           "plan" => "#{@stripe_plan_api_id}",
         ],
       ],
       'default_tax_rates' => [
         "#{@stripe_tax_rate_id}",
       ],
       "expand" => ["latest_invoice.payment_intent"]
     });
Run Code Online (Sandbox Code Playgroud)

w1z*_*n1p 13

谢谢你的问题,爱德华多。

有几种方法可以创建一段Subscription时间,获得客户 SCA 身份验证和稍后对卡收费的许可。假设我们已经创建了一个 Stripe Customer 对象并且他们的 ID 存储在stripe_customer_id. 根据您现在的流程,有几个步骤:

  1. 创建SetupIntent. 请注意,如果您使用 usage: 'off_session' 创建它,Customer它会在确认后附加生成的 PaymentMethod。

    setup_intent = Stripe::SetupIntent.create({
      customer: stripe_customer_id,
      usage: 'off_session',
    })
    
    Run Code Online (Sandbox Code Playgroud)
  2. 收集付款详细信息并client_secret在客户端上使用它来确认 SetupIntent ,这会将 PaymentMethod 附加到客户。请注意,它将附加但不会被设置为invoice_settings.default_payment_method默认情况下,因此您需要稍后进行单独的 API 调用来更新Customer(参见步骤 3)。

     stripe.confirmCardSetup(
       '{{setup_intent.client_secret}}', 
       {
         payment_method: {
           card: cardElement,
         },
       }
     ).then(function(result) {
       // Handle result.error or result.setupIntent
     });
    
    Run Code Online (Sandbox Code Playgroud)
  3. 更新Customer并设置其invoice_settings.default_payment_method等于PaymentMethod成功确认的 SetupIntent 上的ID 。

    Stripe::Customer.update(
      stripe_customer_id, {
      invoice_settings: {
        default_payment_method: 'pm_xxxx', # passed to server from client. On the client this is available on the result of confirmCardSetup 
      }
    })
    
    Run Code Online (Sandbox Code Playgroud)
  4. 创建Subscriptionoff_session: true

    subscription = Stripe::Subscription.create({
      customer: stripe_customer_id,
      proration_behavior: 'create_prorations',
      items: [{
        plan: "#{@stripe_plan_api_id}",
      }],
      default_tax_rates: [
        "#{@stripe_tax_rate_id}",
      ],
      expand: ["latest_invoice.payment_intent"],
      off_session: true,
    })
    
    Run Code Online (Sandbox Code Playgroud)

这使用所谓的“商家发起的交易”(MIT) 进行订阅的第一笔付款。如果订阅是在客户离开之后创建的,并且技术上应该可行,那么这在技术上是可以的。

如果客户在您创建Subscription. Subscription 未经试验的流程如下:

  1. 使用客户端上的 createPaymentMethod 收集卡详细信息(否SetupIntent

    stripe.createPaymentMethod({
      type: 'card',
      card: cardElement,
    }).then(function(result) {
      //pass result to your server.
    })
    
    Run Code Online (Sandbox Code Playgroud)
  2. 将这些卡的详细信息附加到 Customer

    Stripe::PaymentMethod.attach(
      "pm_xxx", {
        customer: stripe_customer_id
      }
    )
    
    Run Code Online (Sandbox Code Playgroud)
  3. 更新Customerinvoice_settings.default_payment_method

    Stripe::Customer.update(
      stripe_customer_id,
      invoice_settings: {
        default_payment_method: @requested_source
      }
    )
    
    Run Code Online (Sandbox Code Playgroud)
  4. 创建Subscription没有 off_session: true

    subscription = Stripe::Subscription.create(
      customer: data['customerId'],
      items: [
        {
          price: 'price_H1NlVtpo6ubk0m'
        }
      ],
      expand: ['latest_invoice.payment_intent']
    )
    
    Run Code Online (Sandbox Code Playgroud)
  5. 使用Subscriptionlatest_invoicepayment_intentclient_secret收集付款细节,并确认客户端上。

    stripe.confirmCardPayment(
      '{{subscription.latest_invoice.payment_intent.client_secret}}', { ......
    
    Run Code Online (Sandbox Code Playgroud)

从 SCA 的角度来看,第二个支付流程更正确,以获得授权以对卡收费。此处的指南概述了第二种方法:https : //stripe.com/docs/billing/subscriptions/fixed-price

我们还有一个条纹示例,您可以在这里进行实验:https : //github.com/stripe-samples/subscription-use-cases/tree/master/fixed-price-subscriptions

  • 如果不将付款方式设置为默认,第一个流程是否也可以工作?因此,我会跳过步骤 3,并在创建订阅时在步骤 4 中添加 `default_ payment_method => pm_xxx`,这应该可以正常工作,对吗? (3认同)
  • 谢谢@cjav_dev,它很有魅力。实际上,我一开始确实实现了第二个流程,但不知何故,在创建订阅后必须验证卡很烦人,所以我最终尝试了第一个流程。“off_session: true”参数就达到了目的。再次感谢! (2认同)
  • 这非常有帮助,谢谢。我想知道为什么第一种方法不太“正确”?我目前正在为我的客户设置 Stripe 订阅集成,第一种方法是唯一可行的方法,因为他们提供 7 天免费试用,因此理想情况下,SCA 流程需要在他们注册时发生,以便可以自动付款审判结束后。 (2认同)