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

NodeJS对接Stripe如何实现manual payout手动打款功能

Stripe 出行场景手动打款给司机的实现指引

你当前用Charges API实现的乘客扣款逻辑,资金默认会直接进入你的Stripe平台主账户,要实现给司机手动结算车费,按以下流程落地即可。

首先先修正你现有支付代码的冗余问题:创建Charge时不需要同时传customer和source参数,传已创建的customer ID后Stripe会自动调用该客户绑定的默认支付方式,重复传source容易触发参数校验错误,修正后核心扣款逻辑如下:

const customer=await stripe.customers.create({
  name: req.body.name,
  email: req.body.email,
  source: req.body.stripeToken,
  address: {
    line1: '510 Townsend St',
    postal_code: '98140',
    city: 'San Francisco',
    state: 'CA',
    country: 'US',
  },
})
const charge=await stripe.charges.create({
  amount: req.body.amount * 100,
  currency: "USD",
  customer: customer.id,
  description: "出行服务乘车费支付",
  receipt_email:req.body.email
})

核心前提说明

乘客支付成功后,资金不会立刻进入可打款的可用余额,会根据你Stripe账户的结算周期(出行类美国账户一般是T+3)进入待结算状态,只有可用余额内的资金才能用来发起打款,不要在支付成功后立刻发起结算。
给司机打款有两种合规方案,根据你的业务复杂度选即可,优先推荐第一种。


方案1:Stripe Connect 转账(平台类业务官方推荐,合规风险最低)

这个方案不需要你直接操作打款到司机银行卡,Stripe会帮你处理KYC校验、打款到卡、税务申报等合规流程,适配出行服务场景。
实现步骤:

  • 给每个注册司机创建Stripe Connect Custom账户,通过Stripe托管的表单引导司机提交身份信息、本地银行卡信息完成KYC审核,审核通过后每个司机对应一个唯一的acct_开头的Connect账户ID,存在本地的司机表中
  • 订单服务完成(乘客确认到达、无投诉)后,等对应订单的资金进入可用余额,调用Transfer接口把扣除平台服务费、通道费后的司机应得金额转到对应司机的Connect账户
  • 你可以给司机的Connect账户设置自动打款规则(比如日结、周结),资金到账后Stripe会自动把钱打到司机绑定的银行卡,不需要你额外调用Payout接口

核心转账代码:

// 计算司机应得金额:总车费 - 平台服务费 - Stripe通道费
const driverAmount = Math.floor((order.totalAmount - platformFee - stripeFee) * 100)
const transfer = await stripe.transfers.create({
  amount: driverAmount,
  currency: "usd",
  destination: driver.connectAccountId, // 提前存储的司机Connect账户ID
  description: `订单${order.orderNo} 乘车费结算`,
  metadata: {
    order_id: order.id,
    driver_id: driver.id
  }
})

配置webhook监听transfer.paid事件,收到事件后再更新本地订单的结算状态,不要用接口同步返回结果作为最终结算成功依据,银行侧处理失败会通过事件回调通知。


方案2:直接发起Manual Payout到司机银行卡(适合小规模简单场景)

如果不想接入Connect,要直接从平台余额打款到司机银行卡,需要先满足两个前提:

  • 提前向Stripe申请开通第三方打款权限:默认Stripe账户只允许打款到你自己绑定的对公/法人银行卡,给第三方个人打款需要提交业务场景说明,审核通过后才能使用
  • 必须通过Stripe官方的安全组件收集司机银行卡信息,禁止自己在服务端存储银行卡号、CVV等敏感信息,收集后绑定为你Stripe账户下的外部收款方,拿到每个银行卡对应的ba_开头的ID存在本地司机表

满足前提后,打款核心代码:

const payout = await stripe.payouts.create({
  amount: driverAmount,
  currency: "usd",
  destination: driver.bankAccountId, // 提前绑定的司机银行卡ID
  description: `订单${order.orderNo} 司机结算`,
  method: 'standard', // standard为标准到账(3个工作日,无额外手续费);instant为即时到账(收1.5%手续费)
  metadata: {
    order_id: order.id,
    driver_id: driver.id
  }
})

必做的校验和风控逻辑

  • 打款前先查询账户可用余额,避免余额不足打款失败:
const balance = await stripe.balance.retrieve()
const availableUsd = balance.available.find(item => item.currency === 'usd').amount
if(availableUsd < driverAmount) throw new Error('可用余额不足,暂时无法结算')
  • 所有打款必须关联真实的订单、司机服务协议记录,Stripe会不定期抽查资金流向,无真实业务背景的打款会触发账户冻结
  • 配置webhook监听payout.failed、payout.paid事件,同步更新结算状态,处理打款失败的退款、重试逻辑
  • 如果采用手动Payout方案,年度给单个司机打款超过600美元时,需要自行给司机开具1099税表完成税务申报,Connect方案下Stripe会自动处理税表流程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 05:33:23