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

Stripe API调用报错求助:密钥无法访问指定cus账户

Stripe API付款错误:无权限访问Customer账户

错误信息

The provided key 'sk_test_***********************************************************************************************JQQa' does not have access to account 'cus_PN***' (or that account does not exist). Application access may have been revoked

代码实现

const stripe = require('stripe')(
   process.env.STRIPE_REAL_API_SECRET_KEY || process.env.STRIPE_TEST_API_SECRET_KEY
);

const eligibleBalanceDueData = res[1].rows.map((row) => ({
    balanceDueId: row.balance_due_id,
    affiliateStripeId: row.stripe_customer_id?.trim(),
    totalAmount: parseFloat(row.total_amount),
}));

for (const item of eligibleBalanceDueData) {
 // Retrieve the Connected Account ID associated with the Customer ID
      const connectedAccountId = await stripe.accounts.listExternalAccounts(
          item.affiliateStripeId,
          { limit: 1, type: 'custom_account' }
      );

      const transfer = await stripe.transfers.create(
          {
              amount: 2, // item.totalAmount * 100, // Amount in cents
              currency: 'usd',
              destination: connectedAccountId.data[0].id,
              transfer_group: 'affiliate_payout',
          },
          {
              idempotencyKey: 'unique_key_here'
          }
      );
}

调用stripe.accounts.listExternalAccounts或stripe.transfers.create时均会触发错误。我认为应使用transfers而非payouts或paymentIntents进行付款,且transfer的destination应为Stripe客户的账户ID。

已确认信息

  • 测试模式下使用的是标准API密钥,具备认证权限;
  • 错误中提及的cus_PN***账户真实存在,与item.affiliateStripeId的值一致;
  • 仅需生成测试付款。

错误详情

{
  type: 'StripePermissionError',
  raw: {
    message: "The provided key 'sk_test_***********************************************************************************************JQQa' does not have access to account 'cus_PNaqkPyNm7hjp4' (or that account does not exist). Application access may have been revoked.",
    type: 'invalid_request_error',
    code: 'account_invalid',
    doc_url: 'https://stripe.com/docs/error-codes/account-invalid',
    headers: {
      server: 'nginx',
      date: 'Tue, 16 Jan 2024 09:11:48 GMT',
      'content-type': 'application/json',
      'content-length': '432',
      connection: 'keep-alive',
      'access-control-allow-credentials': 'true',
      'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
      'access-control-allow-origin': '*',
      'access-control-expose-headers': 'Request-Id, Stripe-Manage-Version, Stripe-Should-Retry, X-Stripe-External-Auth-Required, X-Stripe-Privileged-Session-Required',
      'access-control-max-age': '300',
      'cache-control': 'no-cache, no-store',
      vary: 'Origin',
      'strict-transport-security': 'max-age=63072000; includeSubDomains; preload'
    },
    statusCode: 403,
    requestId: undefined
  },
  rawType: 'invalid_request_error',
  code: 'account_invalid',
  doc_url: 'https://stripe.com/docs/error-codes/account-invalid',
  param: undefined,
  detail: undefined,
  headers: {
    server: 'nginx',
    date: 'Tue, 16 Jan 2024 09:11:48 GMT',
    'content-type': 'application/json',
    'content-length': '432',
    connection: 'keep-alive',
    'access-control-allow-credentials': 'true',
    'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
    'access-control-allow-origin': '*',
    'access-control-expose-headers': 'Request-Id, Stripe-Manage-Version, Stripe-Should-Retry, X-Stripe-External-Auth-Required, X-Stripe-Privileged-Session-Required',
    'access-control-max-age': '300',
    'cache-control': 'no-cache, no-store',
    vary: 'Origin',
    'strict-transport-security': 'max-age=63072000; includeSubDomains; preload'
  },
  requestId: undefined,
  statusCode: 403,
  charge: undefined,
  decline_code: undefined,
  payment_intent: undefined,
  payment_method: undefined,
  payment_method_type: undefined,
  setup_intent: undefined,
  source: undefined
}

错误代码account_invalid的官方描述为:Stripe-Account请求头中的账户ID无效,请检查请求是否指定了有效的账户ID。

已查阅文档和相关帖子仍无法解决,寻求帮助。


解决方案

核心问题定位

你的代码存在两个关键错误:

  1. API误用:stripe.accounts.listExternalAccounts是用于查询Connected Account(前缀acct_)的外部账户,而非Customer(前缀cus_)。传入Customer ID直接触发权限校验失败。
  2. 概念混淆:Transfers API用于平台与Connected Account之间的资金转移,若你的联盟伙伴是Customer身份,不能直接用Transfers到Customer ID,需改为付款到其绑定的支付方式。

修正方案

方案1:给Customer付款到绑定的支付方式

如果联盟伙伴是Customer且已绑定支付方式(银行卡/信用卡),直接创建Transfer到支付方式ID:

for (const item of eligibleBalanceDueData) {
  // 获取Customer的支付方式
  const paymentMethods = await stripe.paymentMethods.list({
    customer: item.affiliateStripeId,
    type: 'card' // 若为银行账户则改为'us_bank_account'
  });

  if (paymentMethods.data.length === 0) {
    throw new Error(`Customer ${item.affiliateStripeId} 未绑定支付方式`);
  }

  // 创建Transfer到支付方式
  const transfer = await stripe.transfers.create({
    amount: Math.round(item.totalAmount * 100), // 转换为分
    currency: 'usd',
    destination: paymentMethods.data[0].id,
    transfer_group: 'affiliate_payout',
  }, {
    idempotencyKey: `payout_${item.balanceDueId}` // 用唯一ID避免重复请求
  });
}

方案2:将联盟伙伴转为Connected Account(适合长期合作场景)

若联盟伙伴是长期合作的商家,建议将其创建为Connected Account,后续用Transfers直接打款:

// 假设已通过OAuth或平台创建流程获取到Connected Account ID(acct_前缀)
for (const item of eligibleBalanceDueData) {
  const transfer = await stripe.transfers.create({
    amount: Math.round(item.totalAmount * 100),
    currency: 'usd',
    destination: item.affiliateConnectedAccountId, // 替换为acct_开头的ID
    transfer_group: 'affiliate_payout',
  }, {
    idempotencyKey: `payout_${item.balanceDueId}`
  });
}

额外检查点

  • 确认API密钥权限:标准密钥默认具备Transfers创建权限,若使用Restricted密钥,需开启transfers:create和payment_methods:read权限;
  • 若使用Connected Account,需确保平台已获得该账户的授权(未被撤销);
  • 测试模式下使用Stripe官方测试支付方式(如卡号4242 4242 4242 4242)。

内容的提问来源于stack exchange,提问作者user8758206

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 02:25:58