使用Stripe Checkout切换订阅计划时,如何处理PaymentActionRequired异常?
解决方案:用Stripe Checkout更新现有订阅(避免重复)
当你使用Cashier的swapAndInvoice方法触发3DS验证这类PaymentActionRequired异常时,完全可以通过Stripe Checkout处理现有订阅的更新,不会生成重复订阅。具体操作步骤如下:
捕获PaymentActionRequired异常
调用swapAndInvoice时捕获异常,从中提取payment_intent对象:try { $user->subscription('default')->swapAndInvoice($newPlanId); } catch (\Laravel\Cashier\Exceptions\PaymentActionRequired $e) { $paymentIntent = $e->paymentIntent; // 后续生成Checkout会话 }创建订阅更新专用的Checkout会话
不要创建新订阅的Checkout会话,直接通过Stripe SDK构建基于现有订阅的更新会话,指定subscription参数为用户现有订阅的Stripe ID:$stripe = new \Stripe\StripeClient(config('cashier.secret')); $session = $stripe->checkout->sessions->create([ 'mode' => 'subscription', 'subscription' => $user->subscription('default')->stripe_id, 'payment_method_types' => ['card'], 'success_url' => route('subscription.success', ['user' => $user->id]), 'cancel_url' => route('subscription.cancel', ['user' => $user->id]), ]);这个会话会引导用户完成必要的支付验证(如3DS),验证通过后自动更新现有订阅,不会产生重复订阅。
重定向用户到Checkout页面
获取会话URL后,直接重定向用户到Stripe Checkout完成验证:return redirect()->to($session->url);处理Webhook回调
确保Stripe Webhook配置正确,监听checkout.session.completed事件。用户完成验证后,Stripe会推送该事件,Cashier会自动同步订阅的更新状态,无需额外手动操作。
注意事项:
- 不要使用Cashier自带的
checkout方法(该方法默认创建新订阅),直接调用Stripe SDK构建更新会话是核心。 - 必须保证现有订阅处于活跃状态,否则无法生成更新会话。
内容的提问来源于stack exchange,提问作者Mateo
相关产品推荐
相关产品推荐

