Stripe转账失败排查:外部账户错误与账户权限异常
Stripe Custom账户转账问题排查与解决
一、核心错误原因分析
1. 转账API调用错误
你误用了stripe.payouts.create接口给连接账户打款——这个接口的作用是给平台自身的外部账户(比如平台自己的银行账户)发起提现,并非用于给连接账户转账。给Custom类型的连接账户转账需要用stripe.transfers.create接口,这也是报错No such external account的直接原因:你把连接账户ID传给了Payout接口的destination参数,但该参数需要的是平台账户下的外部账户ID(如bank_account_xxx),而非连接账户ID。
2. Custom账户能力未激活
从你打印的账户信息可见,capabilities中的card_payments和transfers均为inactive,且payouts_enabled为false,根源是账户缺少合规必填验证信息:
- 未填写
business_type(区分个人/企业账户) - 未提供联系人代表信息(
representative.first_name、representative.last_name) - 未完成服务条款接受(
tos_acceptance.date、tos_acceptance.ip) - 未完善商业信息(
business_profile.mcc、business_profile.url) - 银行账户绑定可能未成功(账户信息中
external_accounts.data为空数组)
二、具体解决步骤
1. 替换转账API:用Transfer替代Payout
将创建Payout的逻辑改为创建Transfer,Transfer接口的destination参数直接传入连接账户ID,同时需确保平台账户有足够余额,或通过source_transaction指定资金来源(如某笔成功的Charge ID)。
2. 补充Custom账户必填信息
创建Custom账户时必须补全requirements字段中列出的所有必填项,否则无法激活转账能力;绑定银行账户后需确认返回结果,必要时处理小额验证流程。
修改后的完整代码
import Stripe from 'stripe'; const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, { apiVersion: '2020-08-27' }); export default async function handler(req, res) { if (req.method === 'POST') { try { const { amount, recipientId, routingNumber, accountNumber, emailId, businessType, repFirstName, repLastName, userIp } = req.body; let recipientAccountId; if (recipientId) { recipientAccountId = recipientId; } else { // 创建Custom账户时补充所有必填合规信息 const account = await stripe.accounts.create({ type: 'custom', country: 'US', email: emailId, business_type: businessType, // 个人填"individual",企业填"company" representative: { first_name: repFirstName, last_name: repLastName }, business_profile: { mcc: '5812', // 根据业务选对应MCC码,示例为餐饮类 url: 'https://your-seller-business-url.com' // 卖家业务网站地址 }, tos_acceptance: { date: Math.floor(Date.now() / 1000), ip: userIp // 卖家的IP地址 }, capabilities: { card_payments: {requested: true}, transfers: {requested: true}, }, }); recipientAccountId = account.id; console.log("customAccount", account) // 绑定银行账户并确认结果 const externalAccount = await stripe.accounts.createExternalAccount(recipientAccountId, { external_account: { object: 'bank_account', country: 'US', currency: 'usd', routing_number: routingNumber, account_number: accountNumber } }); console.log("绑定的外部账户", externalAccount); } // 使用Transfer接口给连接账户转账 const transfer = await stripe.transfers.create({ amount, currency: 'usd', destination: recipientAccountId, // 可选:指定资金来源,如某笔Charge的ID // source_transaction: 'ch_xxx' }); res.status(200).json({ transferId: transfer.id }); } catch (error) { console.error(error); res.status(500).json({ error: error.message || '转账发起失败' }); } } else { res.setHeader('Allow', 'POST'); res.status(405).end('Method Not Allowed'); } }
三、额外注意事项
- 银行账户绑定后,Stripe可能会发起小额验证(打两笔几分钱的款项),需要卖家确认金额后完成验证,否则账户无法正常接收转账。
- 不同地区的Custom账户必填项存在差异,需根据目标地区合规要求补充信息。
- 确保平台账户有足够余额用于转账,或通过
source_transaction指定资金来源,避免余额不足报错。
内容的提问来源于stack exchange,提问作者gauthami vijay
相关产品推荐
相关产品推荐

