Stripe问题:单次付款后客户未绑卡无法创建订阅
问题原因
Stripe Checkout的mode=payment(单次付款)模式默认不会将客户的付款方式保存到其账户中,而mode=subscription模式为了支持后续自动扣费,会自动保存付款方式并设为默认。这就是你创建订阅时触发This customer has no attached payment source or default payment method.错误的核心原因。
解决方案
有两种可靠的方式解决这个问题:
方案1:创建Checkout Session时直接指定保存付款方式
在创建单次付款的Checkout Session时,添加setup_future_usage参数,告知Stripe将付款方式保存下来,用于未来的离线扣费场景(比如订阅自动扣款)。
修改后的Checkout Session创建代码:
$checkout_session = Session::create([ 'payment_method_types' => ['card'], 'mode' => 'payment', 'customer' => 'cus_xxxxxxxx', 'line_items' => [[ 'price' => 'price_xxxxx', // 单次付款价格 'quantity' => 1, ]], 'setup_future_usage' => 'off_session', // 关键参数:保存付款方式用于后续离线付款 ]);
添加该参数后,客户完成付款后,付款方式会自动绑定到指定客户账户,并设置为默认付款方式,后续创建订阅时即可直接使用。
方案2:通过Webhook手动绑定付款方式
如果不想在创建Checkout Session时提前指定保存逻辑,也可以在付款成功后,通过checkout.session.completed事件的Webhook,将付款方式手动附加到客户账户。
步骤1:编写Webhook处理代码
当Checkout Session付款完成时,Stripe会推送checkout.session.completed事件,你可以在Webhook端点中获取对应的PaymentIntent和PaymentMethod,完成绑定操作:
// Webhook端点处理代码示例 $payload = @file_get_contents('php://input'); $sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE']; $event = null; try { $event = \Stripe\Webhook::constructEvent( $payload, $sig_header, '你的Webhook密钥' ); } catch(\UnexpectedValueException $e) { // 请求体无效 http_response_code(400); exit(); } catch(\Stripe\Exception\SignatureVerificationException $e) { // 签名验证失败 http_response_code(400); exit(); } // 处理checkout.session.completed事件 if ($event->type == 'checkout.session.completed') { $session = $event->data->object; $customer_id = $session->customer; $payment_intent_id = $session->payment_intent; // 获取PaymentIntent对象 $payment_intent = \Stripe\PaymentIntent::retrieve($payment_intent_id); $payment_method_id = $payment_intent->payment_method; // 将PaymentMethod附加到客户,并设置为默认付款方式 \Stripe\PaymentMethod::attach( $payment_method_id, ['customer' => $customer_id] ); \Stripe\Customer::update( $customer_id, ['invoice_settings' => ['default_payment_method' => $payment_method_id]] ); } http_response_code(200);
步骤2:配置Stripe Webhook
在Stripe后台的Webhook设置中,确保checkout.session.completed事件已添加到你的端点并启用。
验证
完成任一方案后,客户完成单次付款后,你可以在Stripe Dashboard的客户详情页看到已绑定的付款方式,此时执行你原有的订阅创建代码,即可正常完成订阅创建。
内容的提问来源于stack exchange,提问作者LoickMEYER

