我正在尝试使用SetupIntents来验证和保存付款方式,然后使用它创建订阅以向客户(立即,然后每月(收取所需金额的费用。
这似乎工作正常:
- 该卡已验证(如果需要,包括 SCA(
- 将创建付款方式,默认附加到客户,并启用以供将来使用,状态为"成功"。
- 订阅已创建并使用上述付款方式
问题在于,只要提供的卡需要安全客户授权 (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"]
});
谢谢你的问题,爱德华多。
有几种方法可以创建Subscription
,同时获得客户 SCA 身份验证和稍后向卡收费的权限。假设我们已经创建了一个 Stripe 客户对象,并且他们的 ID 存储在stripe_customer_id
中。对于您现在拥有的流程,有几个步骤:
-
创建
SetupIntent
.请注意,如果您使用用法创建它:"off_session"和Customer
,它将在确认后附加生成的付款方式。setup_intent = Stripe::SetupIntent.create({ customer: stripe_customer_id, usage: 'off_session', })
-
收集付款详细信息并使用其在客户端上的
client_secret
确认 SetupIntent,这会将付款方式附加到客户。请注意,默认情况下,它将附加但不设置为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 });
-
更新
Customer
并将其invoice_settings.default_payment_method
设置为等于成功确认的 SetupIntent 上PaymentMethod
的 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 } })
-
使用
off_session: true
创建Subscription
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, })
这将使用所谓的"商家发起的交易"(MIT(作为订阅的第一笔付款。如果订阅是在客户离开后稍后创建的,并且在技术上应该可以工作,则这在技术上是可以的。
如果在您创建Subscription
时客户在您的网站/应用程序上,则还有另一个流程更正确一些,并且不需要对 SCA 使用 MIT 豁免。对于没有试用版的Subscription
,流程如下:
-
在客户端上使用创建付款方式收集卡详细信息(无
SetupIntent
(stripe.createPaymentMethod({ type: 'card', card: cardElement, }).then(function(result) { //pass result to your server. })
-
将这些卡详细信息附加到
Customer
Stripe::PaymentMethod.attach( "pm_xxx", { customer: stripe_customer_id } )
-
更新
Customer
的invoice_settings.default_payment_method
Stripe::Customer.update( stripe_customer_id, invoice_settings: { default_payment_method: @requested_source } )
-
创建
Subscription
(不带off_session: true
(subscription = Stripe::Subscription.create( customer: data['customerId'], items: [ { price: 'price_H1NlVtpo6ubk0m' } ], expand: ['latest_invoice.payment_intent'] )
-
使用
Subscription
latest_invoice
payment_intent
client_secret
收集付款详细信息并在客户端上确认。stripe.confirmCardPayment( '{{subscription.latest_invoice.payment_intent.client_secret}}', { ......
从SCA的角度来看,第二个支付流程更正确一些,以获得向卡收费的授权。指南中概述了第二种方法:https://stripe.com/docs/billing/subscriptions/fixed-price
我们还有一个条纹示例,您可以使用此处进行实验:https://github.com/stripe-samples/subscription-use-cases/tree/master/fixed-price-subscriptions