Laravel Cashier中多Stripe客户复用同一支付方式ID的问题
解决Stripe支付方式已绑定客户的订阅创建问题
问题场景
我的应用包含company和reader两种订阅级别,用户A已开通company订阅,现在需要为用户B开通reader订阅。尝试使用用户A在Stripe中绑定的同一支付方式ID为用户B创建订阅时,触发报错:
"The payment method you provided has already been attached to a customer."
示例代码:
$user = User::where('id', 26)->first(); $user->subscription('company')->incrementQuantity(1); $paymethod = $user->defaultPaymentMethod(); $id = 28; $user2 = User::where('id', $id)->first(); $user2->newSubscription('reader', 'price_xxx')->create($paymethod->id);
问题原因
Stripe的支付方式(PaymentMethod)是与单个客户(Customer)绑定的,一旦关联到某个客户,就不能直接用于其他客户的订阅创建,这是平台的安全机制,防止支付方式被未经授权的使用。
可行解决方案
方案1:转移支付方式到目标客户
直接将用户A的支付方式从其Stripe客户对象转移到用户B的客户对象,之后就能用该支付方式为用户B创建订阅。注意:转移后用户A将无法再使用该支付方式,除非再次转移回去。
代码示例:$userA = User::where('id', 26)->first(); $paymentMethodId = $userA->defaultPaymentMethod()->id; $userB = User::where('id', 28)->first(); // 执行支付方式转移 \Stripe\PaymentMethod::update( $paymentMethodId, ['customer' => $userB->stripe_id] ); // 为用户B创建订阅 $userB->newSubscription('reader', 'price_xxx')->create($paymentMethodId);方案2:克隆支付方式(保留原用户的支付方式)
如果需要让用户A继续使用该支付方式,可以通过SetupIntent为用户B创建一个支付方式副本,无需用户重新输入卡片信息。
代码示例:$userA = User::where('id', 26)->first(); $userB = User::where('id', 28)->first(); $originalPaymentMethodId = $userA->defaultPaymentMethod()->id; // 创建并确认SetupIntent,生成新的支付方式 $setupIntent = \Stripe\SetupIntent::create([ 'customer' => $userB->stripe_id, 'payment_method' => $originalPaymentMethodId, 'transfer_data' => [ 'destination' => $userB->stripe_id, ], 'confirm' => true, ]); // 使用新生成的支付方式创建订阅 $userB->newSubscription('reader', 'price_xxx')->create($setupIntent->payment_method);方案3:共享客户账户(适合同企业用户)
如果用户A和B属于同一企业,可将用户B的订阅关联到用户A的Stripe客户账户下,统一由用户A支付账单。通过元数据标记订阅所属的实际用户ID即可。
代码示例:$userA = User::where('id', 26)->first(); // 为用户A的客户添加reader订阅,并标记归属用户B $userA->newSubscription('reader_userB', 'price_xxx')->create(null, [ 'metadata' => ['linked_user_id' => 28] ]);
内容的提问来源于stack exchange,提问作者poorman47
相关产品推荐
相关产品推荐

