关于Stripe Payments API实现分项捕获/取消付款及手续费的技术咨询
首先明确:Stripe Payments/Checkout API本身不支持直接按单个line-item拆分捕获或取消操作,因为Payment Intent是基于整体授权金额设计的,而非绑定具体商品项。但结合你的需求,可以通过「手动分批次捕获+自定义元数据记录状态」的方式,在单个Payment Intent内实现所有操作,无需切换到Invoice API。
具体实现步骤
1. 创建包含总金额的手动捕获Payment Intent
提交表单时,创建Payment Intent,总金额设为「所有服务的手续费总和 + 所有服务的主体金额总和」,并设置capture_method: manual(开启延迟捕获)。
同时在metadata字段中记录每个服务的明细,比如:{ "services": "[ {\"id\": \"s1\", \"fee\": 100, \"amount\": 500, \"fee_captured\": false, \"approved\": false}, {\"id\": \"s2\", \"fee\": 150, \"amount\": 600, \"fee_captured\": false, \"approved\": false} ]" }(注:metadata值需为字符串,所以要把JSON数组转成字符串存储)
2. 即时捕获所有服务的手续费
表单提交成功后,立即调用PaymentIntent.capture接口,捕获金额设为所有服务的手续费总和。同时更新Metadata中对应服务的fee_captured: true,标记手续费已收取。
如果需要收取平台应用手续费(application fee),可以在此次捕获时指定application_fee_amount为手续费对应的平台分成金额。3. 单独处理每个服务的主体金额
- 当某服务审批通过:再次调用
PaymentIntent.capture,捕获金额设为该服务的主体金额,同时更新Metadata中该服务的approved: true,标记服务金额已捕获。 - 当某服务审批不通过:无需额外捕获操作,只需在Metadata中标记该服务
approved: false,后续放弃对应金额的授权即可。
- 当某服务审批通过:再次调用
4. 收尾处理剩余授权
所有服务处理完成后,若还有未捕获的金额(对应未审批服务的主体金额),可以调用PaymentIntent.cancel主动取消剩余授权,或等待授权自动过期(不同卡组织的授权有效期为7-30天不等)。
关键注意事项
- 分批次捕获的总金额不能超过Payment Intent的初始授权金额。
- 已捕获的金额无法撤销,只能通过退款操作处理(若后续需要退还某服务的手续费或主体金额)。
- Metadata仅用于你自身记录业务状态,Stripe不会基于Metadata自动执行任何操作,需自行维护状态一致性。
关于其他方案的说明
- 无需使用Invoice API:Invoice API适用于订阅、定期账单等需要生成正式发票的场景,你的需求用Payments API完全可以覆盖。
- 增量授权不适用:增量授权是用于增加已授权的金额,而你的需求是拆分现有授权金额的捕获,两者场景不符,无需采用。
内容的提问来源于stack exchange,提问作者Bryan

