如何在两个不同Stripe账户中创建或获取相同客户
问题原因
你遇到的问题核心是Laravel Cashier(你调用的createOrGetStripeCustomer是Cashier提供的方法)默认会将Stripe客户ID持久化到业务模型的stripe_id字段中,而Stripe的所有资源ID都是账户隔离的,同一个客户在两个Stripe账户中的ID完全独立,不能共用:
- 第一次循环使用第一个账户的密钥执行时,
createOrGetStripeCustomer会创建客户,并将生成的客户ID写入$hotel模型的stripe_id字段 - 第二次循环切换到第二个账户的密钥后,
createOrGetStripeCustomer检测到stripe_id字段已有值,会直接用第一个账户生成的客户ID去第二个账户查询,查不到也不会触发新建逻辑,因此第二个账户没有生成数据,且不会抛错
解决方法
前置准备
如果需要长期存储两个账户的客户ID,先给hotels表新增第二个Stripe账户的客户ID存储字段,例如stripe_id_mapping,避免两个账户的ID互相覆盖。
调整后代码
// 按账户配置独立的密钥和对应存储字段 $stripeAccounts = [ [ 'secret' => env('STRIPE_SECRET'), 'id_field' => 'stripe_id' ], [ 'secret' => env('STRIPE_SECRET_MAPPING_MASTER'), 'id_field' => 'stripe_id_mapping' ] ]; $hotel = session('hotel'); foreach ($stripeAccounts as $account) { // 切换当前Stripe账户密钥 Stripe::setApiKey($account['secret']); // 临时覆盖模型的stripe_id为当前账户对应存储的值,避免复用其他账户的ID $hotel->stripe_id = $hotel->{$account['id_field']}; // 此时如果当前账户的ID为空,会自动创建新客户 $stripeUser = $hotel->createOrGetStripeCustomer(); // 将当前账户生成的客户ID存入对应字段,不覆盖其他账户的ID $hotel->{$account['id_field']} = $stripeUser->id; // 支付方法同步注意:支付方法ID也是账户隔离的,不能直接复用第一个账户的ID // 如果需要同步支付方法,需要先将支付方法克隆到当前账户再附着,示例逻辑如下: // $originPm = \Stripe\PaymentMethod::retrieve('第一个账户的支付方法ID'); // $clonedPm = $originPm->clone(['customer' => $stripeUser->id]); // $hotel->updateDefaultPaymentMethod($clonedPm->id); } // 保存两个账户的客户ID $hotel->save();
补充说明
如果不需要持久化存储第二个账户的客户ID,仅需要单次创建,也可以在第二次循环前手动清空$hotel->stripe_id的值,同时避免调用save()方法覆盖原有第一个账户的ID即可。
内容的提问来源于stack exchange,提问作者GPiter
相关产品推荐
相关产品推荐

