Stripe 的 PaymentIntent、Charge、Balance Transaction、Pending Balance、Available Balance、Payout 和银行入账有什么区别?
Stripe 后台同时出现“支付成功”“余额待结算”“余额可用”“打款已发出”和“银行已入账”时,最容易发生的错误,是把它们理解成同一个状态的不同叫法。实际上,它们属于一条资金链上的不同对象与时间点:PaymentIntent 管支付流程,Charge 记录具体支付尝试,Balance Transaction 记录 Stripe 余额的账本变化,pending 与 available 表示资金可用性,Payout 表示从 Stripe 余额向外部账户打款,而银行入账是收款银行最终记账的结果。
本文目录(14 节)
一句话区分
| 名称 | 它回答的问题 | 常见 ID 或字段 |
|---|---|---|
| PaymentIntent | 这笔订单的收款流程进行到哪里 | pi_...、status、latest_charge |
| Charge | 某一次实际支付尝试发生了什么 | ch_...、status、balance_ |
| Balance Transaction | 这项活动怎样增加或减少 Stripe 余额 | txn_...、amount、fee、net、available_on |
| Pending Balance | 哪些资金已经进入账本、但尚不可用于普通打款 | Balance 的 pending |
| Available Balance | 哪些资金当前可用于打款、退款或其他余额支出 | Balance 的 available |
| Payout | Stripe 余额中的资金何时、以多少金额汇往外部账户 | po_...、status、arrival_date |
| 银行入账 | 外部银行是否已经把该笔打款记入账户 | 银行流水参考号、入账日 |
这七项不是七选一的状态。一次正常收款可能依次产生或关联其中多项,而且关系通常不是简单的一对一。
PaymentIntent:面向订单的支付状态机
PaymentIntent 用来跟踪一次支付从创建、确认、客户验证到成功或失败的生命周期。它适合与购物车、订单或一次结账会话绑定。遇到 3D Secure、异步支付方式或支付方式被拒绝时,应用应读取 PaymentIntent 的状态决定下一步,而不是仅凭前端跳转页判断结果。
同一个 PaymentIntent 可能因为重试关联多个 Charge,但最终至多有一个成功的 Charge。因此,pi_... 更接近“这笔订单要收多少钱以及收款流程怎样”,并不等于一条银行流水。支付失败后更换卡重试时,通常仍应复用同一个 PaymentIntent,以保留完整尝试历史;业务侧还应使用幂等键,避免为同一订单意外创建重复意图。
Charge:一次支付尝试的记录
Charge 表示具体的扣款尝试,包含支付方式结果、风控结果、收据和退款相关信息。查看失败原因、卡品牌、授权结果或该次尝试关联的余额交易时,Charge 比 PaymentIntent 更具体。
但是,Charge 成功只说明支付流程成功完成,不代表净额已经可以打到银行。手续费会改变净额,结算周期会让资金先处于 pending,退款或争议还可能产生新的负向余额交易。订单履约可以依据经过服务端验证的支付成功事件,但现金可用性和财务对账不能只看 Charge 的 paid 或 PaymentIntent 的 succeeded。
Balance Transaction:Stripe 余额的账本凭证
Balance Transaction 是理解资金变化的核心。Stripe 会为进入或流出账户余额的多类活动创建余额交易,例如付款、退款、争议、费用、转账和打款。其常用字段包括:
amount:该交易的总金额影响;fee:该交易计收的费用;net:对 Stripe 余额的净影响,通常可由amount - fee得到;currency:该账本条目采用的币种;status:净资金处于pending还是available;available_on:预计何时成为可用余额;source:关联的 Charge、Payout、Refund 等源对象;reporting_:适合财务分类的报告类别。category
财务报表不应只拿 Charge 金额减一个固定费率来推算净额。不同支付方式、跨境费用、税费和汇兑都会使实际费用不同,应以 Balance Transaction 的实际 fee、net 和 exchange_rate 为准。Stripe 也建议会计分类优先采用 reporting_,而不是把技术性的 type 直接当作总账科目。
Pending Balance:已经记录,但尚不可普通提取
付款进入 Stripe 余额后,净额通常先显示为 pending。它表示交易已经影响账户,但尚未完成适用的结算等待期,普通打款或余额支出不能直接使用这部分资金。
pending 不是支付失败,也不是 Stripe 忘了打款。结算时间会因账户所在国家或地区、支付方式、交易类型、风险状况以及是否为首次打款而变化。判断单条资金何时转为可用,应查看对应 Balance Transaction 的 available_on,不要在代码中写死“支付成功后两天到账”。符合条件的 Instant Payout 等能力可能采用不同机制,但不能据此把所有 pending 都视为立即可提取。
Available Balance:可以使用的 Stripe 余额
当结算完成后,资金从 pending 转入 available。可用余额通常可以用于向银行打款、退款、转账或其他余额扣项。Balance API 会按币种返回 available 和 pending;部分场景还会按支付来源细分。
可用余额也不等于下一笔银行入账金额。账户可能有多币种余额、最低余额、储备金、负余额、退款或争议扣款;自动打款计划还会按周期把多项活动合并。财务系统应分别维护 Stripe 清算账户和银行账户,不能在 PaymentIntent 成功时直接把净额记为银行存款。
Payout:从 Stripe 余额向外部账户转出
Payout 表示 Stripe 将资金发送到外部银行账户或符合条件的借记卡。它有自己的生命周期和状态。自动打款通常把一个结算批次中的多笔余额活动合并成一笔 Payout,因此一笔 Payout 可能对应许多付款、手续费、退款和调整;一笔 Charge 也未必能单独对应某笔打款。
手动打款更像从 Stripe 清算账户中自主转出指定金额。即时打款由商户控制时间和金额,Stripe 的自动打款对账报告无法总是替你确定其包含哪些原始交易,因此需要依据余额历史自行核对。创建 Payout 前应检查币种和可用余额,监听打款成功、失败或取消事件,并让重试操作保持幂等。
银行入账:外部金融机构的最终记账
Payout 在 Stripe 侧进入成功或已支付状态,与银行网银中已经显示入账并非完全同一时刻。arrival_date 是预计或适用的到账日期,实际显示仍可能受银行处理时段、周末、节假日、当地清算网络和账户信息影响。
所以客户付款成功时间、资金转为 available 的时间、Payout 创建时间、Stripe 标记打款完成时间以及银行流水入账时间应分栏保存。银行对账应使用 Payout ID、银行参考信息、币种、金额和日期窗口组合匹配,并保留人工处理无法唯一匹配项目的入口。
一笔订单如何穿过整条链路
假设订单金额为 100 美元:
- 系统为订单创建
pi_...,客户第一次尝试失败,产生一次失败尝试; - 客户换卡重试,PaymentIntent 最终成功,并产生成功的
ch_...; - 成功 Charge 关联
txn_...,其中记录总额、实际手续费与净额; - 净额先进入 USD pending,并由
available_on指示预计可用时间; - 结算完成后,净额进入 USD available;
- 自动打款计划把该净额与同批次其他付款、退款、费用合并到
po_...; - 外部银行最终将 Payout 记入银行流水。
如果这期间发生退款,系统会看到新的负向余额交易,而不是修改掉原来的付款账本事实。若发生争议、打款失败或汇率转换,也会产生相应活动。因此财务链应以不可变事件和关联 ID 重建,而不是覆盖原记录。
推荐的数据关联方式
订单表至少保存业务订单号和 PaymentIntent ID;支付尝试表保存 Charge ID、PaymentIntent ID、尝试结果与时间;余额流水表保存 Balance Transaction ID、source、amount、fee、net、currency、status、available_on 和 reporting_
金额必须使用最小货币单位的整数,币种必须参与联合判断。不要用浮点数比较,也不要跨币种直接相加。对象同步应以上游对象 ID 做唯一键,Webhook 消费应按 Event ID 去重,主动补偿查询也要采用 upsert,以便事件重复、乱序或短暂丢失时仍能恢复一致状态。
状态判断应该服务于不同业务动作
- 是否向客户展示“付款完成”:验证服务端 PaymentIntent/
Charge 结果和可信 Webhook; - 是否可以履约:按商品风险和支付方式决定,异步方式不要只看前端回跳;
- 是否可发起普通 Payout:查看正确币种的 available balance;
- 某笔净收入是多少:读取相关 Balance Transaction 的
net; - 某次自动打款包含哪些交易:使用 Payout reconciliation 报告或对应 API 数据;
- 银行是否真的收到:以银行流水完成最终核销。
把不同问题交给正确对象,既能减少误发货,也能避免“Stripe 显示成功但银行没到账”这类概念混乱。
常见错误与修正
用 PaymentIntent 金额当净收入
PaymentIntent 表示拟收取或已收取的支付金额,不包含所有账本层面的费用与后续调整。净收入应基于 Balance Transaction。
用 Charge 成功当作余额可打款
成功 Charge 与结算可用是两个阶段。应检查余额交易状态及 available_on,发起打款时再检查 available balance。
按金额寻找“一一对应”的 Payout
自动 Payout 往往是批次净额。应通过 Stripe 的打款对账数据关联批次,不要在许多相同金额中猜测。
忽略退款和争议的独立账本条目
退款与争议会产生新的余额影响。覆盖原 Charge 金额会破坏审计链,也难以解释历史报表。
把预计到账日当银行确认日
预计日期用于跟踪异常,不是银行最终凭证。最终核销仍应读取银行流水。
FAQ
1. PaymentIntent succeeded 后,钱已经到银行了吗?
没有。它说明支付流程成功,之后还要经过 Stripe 余额结算、可用余额、Payout 和银行处理等阶段。
2. 一个 PaymentIntent 会有多个 Charge 吗?
可能。失败后重试可以留下多个 Charge 记录,但一个 PaymentIntent 最终至多有一个成功 Charge。排查支付尝试时应查看完整关联记录。
3. Charge 金额为什么和 Balance Transaction 的 net 不同?
因为 net 反映扣除实际费用后对余额的净影响;跨币种场景还可能涉及汇率。应读取余额交易的实际字段,而非自行估算。
4. pending 中的钱是否一定会在固定两天后可用?
不一定。结算时间取决于国家或地区、支付方式、账户阶段和交易类型等因素,应以官方适用规则与单笔 available_on 为准。
5. available balance 是否会全部进入下一笔 Payout?
不一定。币种、打款计划、最低余额、储备、负向交易和账户配置都可能影响实际打款金额。
6. Payout 显示 paid,银行却没看到怎么办?
先核对外部账户、币种、预计到账日和银行处理日,再使用 Payout 的参考信息向银行查询。超过合理窗口仍未入账时,通过 Stripe 支持渠道排查,不要重复创建同额打款来“试一次”。
7. 自动 Payout 怎样和订单对账?
使用 Payout reconciliation 报告或 API 数据,把打款批次与其包含的余额交易关联,再由余额交易的 source 回溯 Charge、Refund 等对象,最终连接业务订单。
8. 财务分类应该使用 Balance Transaction 的 type 吗?
Stripe 建议会计用途优先使用 reporting_。type 更偏底层交易类型,随着产品和资金机制增加,直接映射总账科目容易变得脆弱。