在Laravel中配置Stripe Checkout链接以自动使用用户默认支付方式(无需输入卡片信息)
看起来你已经走在正确的路上了——你已经在Checkout Session里指定了customer参数,这是复用用户已有支付方式的核心前提!要让Stripe Checkout自动使用用户的默认支付方式,不需要用户再输入卡片信息,只需要对Checkout Session的配置做几个小调整就行,我来一步步给你说明:
关键参数调整
你需要修改生成Checkout Session的$payload数组,添加/调整以下几个核心参数:
添加
payment_method_collection: 'if_required'
这个参数会告诉Stripe:只有当当前客户没有可用的支付方式时,才显示卡片输入界面。如果客户已经有默认支付方式(比如你之前通过API附加的那种),Checkout会直接跳过支付方式输入步骤,自动调用默认的支付方式完成流程。优化账单地址收集(可选但推荐)
你当前设置了billing_address_collection: 'required',这会强制Checkout重新收集账单地址,哪怕客户的Stripe档案里已经存有完整地址。可以把它改成'auto',这样Stripe会自动复用客户已有的账单地址,只有当地址缺失时才会要求用户补充。可选:移除
payment_method_types
Stripe会自动识别客户已有的支付方式类型,保留这个参数也没问题,但如果想让Stripe自动适配客户的可用支付方式,可以考虑移除它,让Stripe自行处理兼容的支付方式类型。
修改后的完整代码
把你的Checkout Session生成代码调整为如下版本:
$payload = [ 'success_url' => config('services.accounts.base_url') . "/plan-callback?". http_build_query([ 'subscription' => $subscription->id, 'price' => $price->id ]) . '&subscription_id={CHECKOUT_SESSION_ID}', 'cancel_url' => config('services.accounts.base_url') . "/plans/".$price->id."/change", // 可选:移除该参数,让Stripe自动适配客户可用支付方式 // 'payment_method_types' => ['card'], 'mode' => 'subscription', 'billing_address_collection' => 'auto', // 自动复用客户已有账单地址 'payment_method_collection' => 'if_required', // 仅在无可用支付方式时才收集 'line_items' => [ [ 'price' => $planId, 'quantity' => 1 ] ], 'metadata' => [ 'user' => $user->id ], 'customer' => $user->stripe_customer_id, // 必须保留,指定要复用支付方式的客户 ]; $response = Cashier::client('stripe')->checkout->create($payload); if ($response) { return $response->url ?? null; }
前提条件确认
要确保这个方案生效,你需要额外确认一个点:
你的用户对应的Stripe Customer对象(即$user->stripe_customer_id指向的对象)必须已经设置了默认支付方式。你之前的代码已经把支付方式附加到客户,但别忘了把它设为默认!如果之前没做这一步,可以在附加支付方式的代码后添加这一行:
// 在你附加支付方式的代码末尾添加,设置该支付方式为客户默认 $stripe->customers->update( auth()->user()->stripe_customer_id, ['invoice_settings' => ['default_payment_method' => $paymentDetail->id]] );
额外说明
- 如果客户有多个支付方式,Stripe Checkout会自动使用他们设置的默认选项;如果想让用户可以手动选择已有支付方式,只需要去掉
payment_method_collection: 'if_required',Checkout会显示已有的支付方式列表,用户无需重新输入卡片信息。 - 这个方案完全兼容你当前使用的Stripe PHP SDK v13+和Laravel 9版本,没有兼容性问题。
备注:内容来源于stack exchange,提问作者Kaushal Joshi

