带试用期的Stripe订阅与Payment Intent整合支付流问题咨询
解决方案与问题分析
核心问题根源
带试用期时,后续订阅扣费属于off_session支付,但你的流程未在用户on_session(结账时)完成3DS验证并将支付方式标记为可用于off_session,导致后续扣费触发强制3DS要求,最终支付失败。
一、保留试用期的可行支付流调整
方案:合并一次性产品费用与订阅初始发票,单次完成支付+3DS验证+支付方式保存
取消单独创建产品PaymentIntent的步骤,直接在用户选择订阅时,将一次性产品作为发票项附加到订阅中,通过同一个PaymentIntent完成所有操作:
后端创建订阅的代码调整
关键添加payment_method_options标记支付方式可用于off_session,确保用户on_session支付时完成3DS验证:$subscriptionStripe = $stripe->subscriptions->create([ 'customer' => $customer, 'items' => [ ['price' => $planEntity->getStripePaymentLinkMonthly()], ], 'payment_behavior' => 'default_incomplete', 'add_invoice_items' => [['price' => $price]], // 附加一次性产品价格 'expand' => ['latest_invoice.payment_intent'], 'trial_end' => $trial_end, // 核心配置:标记支付方式可用于后续off_session扣费 'payment_method_options' => [ 'card' => [ 'setup_future_usage' => 'off_session' ] ], ]); // 直接获取订阅发票关联的PaymentIntent密钥,返回给前端 $client_secret = $subscriptionStripe->latest_invoice->payment_intent->client_secret;前端处理逻辑
用上述client_secret初始化支付元素,用户完成支付后:- 一次性产品费用会被即时收取
- 支付方式自动保存到客户账户,并标记为可用于off_session
- 订阅进入试用期,后续扣费(试用期结束后)将自动使用该支付方式,无需额外3DS验证
二、关于初始PaymentIntent的问题
无法更新已创建的PaymentIntent来包含订阅发票。PaymentIntent是一次性、金额固定的支付对象,创建后无法修改核心属性(如关联对象、金额)。建议直接取消未完成的初始PaymentIntent:
$stripe->paymentIntents->cancel($initial_payment_intent_id);
三、先付一次性再off_session付订阅失败的修复
如果坚持分开支付流程,需确保以下两点:
- 支付一次性产品时,明确设置
setup_future_usage并修复参数错误:$paymentIntent = $stripe->paymentIntents->create([ 'setup_future_usage' => 'off_session', 'customer' => 'customer_id', 'currency' => 'usd', 'amount' => 4999, // 注意:此处应为数字,原代码字符串格式存在语法错误 'automatic_payment_methods' => ['enabled' => true], ]); - 支付完成后,将该支付方式设置为客户默认支付方式:
$stripe->customers->update($customer_id, [ 'invoice_settings' => [ 'default_payment_method' => $payment_method_id, ], ]);
额外注意事项
- 原代码中
amount字段存在语法错误(字符串未闭合且应为数字类型),修复后才能正常创建PaymentIntent - 确保Stripe账户已开启自动支付方法,3DS验证设置符合业务地区的合规要求
内容的提问来源于stack exchange,提问作者thexcoach
相关产品推荐
相关产品推荐

