You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在两个不同Stripe账户中创建或获取相同客户

问题原因

你遇到的问题核心是Laravel Cashier(你调用的createOrGetStripeCustomer是Cashier提供的方法)默认会将Stripe客户ID持久化到业务模型的stripe_id字段中,而Stripe的所有资源ID都是账户隔离的,同一个客户在两个Stripe账户中的ID完全独立,不能共用:

  1. 第一次循环使用第一个账户的密钥执行时,createOrGetStripeCustomer会创建客户,并将生成的客户ID写入$hotel模型的stripe_id字段
  2. 第二次循环切换到第二个账户的密钥后,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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 16:18:03