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

使用Customer Source时Stripe Charges失败问题排查

解决Stripe扣款报错"Must provide source or customer"的问题

我来帮你排查这个问题,结合你提供的代码和描述,可能有以下几个关键点需要检查:

1. 调整参数设置的正确姿势

Stripe的Go SDK中,用客户名下的源发起扣款时,更规范的做法是直接绑定客户ID,而非单独传入源对象。你当前的代码只传入了源,但没有关联客户,这可能导致Stripe无法识别该源所属的上下文,从而触发报错。

你可以修改代码为两种方式:

  • 方式一:让Stripe使用客户的默认支付源
params := &stripe.ChargeParams{
    Amount:      stripe.Int64(int64(order.total * 100)),
    Currency:    stripe.String(string(stripe.CurrencyUSD)),
    Description: stripe.String("Order Number " + order.ID),
    Customer:    stripe.String(sc.ID), // 直接绑定客户ID
}
  • 方式二:指定客户名下的特定源(非默认源)
params := &stripe.ChargeParams{
    Amount:      stripe.Int64(int64(order.total * 100)),
    Currency:    stripe.String(string(stripe.CurrencyUSD)),
    Description: stripe.String("Order Number " + order.ID),
    Customer:    stripe.String(sc.ID),
    Source:      stripe.String(sc.Sources.Data[1].ID), // 传入源的ID而非整个对象
}

2. 检查源数组的索引是否正确

你代码中用了sc.Sources.Data[1],但Stripe返回的源数组是从0开始索引的。如果客户只有1个支付源,Data[1]会指向不存在的元素,导致传入无效的源信息。建议先打印源数组的长度确认:

fmt.Println("客户源数量:", len(sc.Sources.Data))

如果数量为1,应该使用Data[0]来获取有效源。

3. 确认源的状态是否可扣款

即使能获取到源对象,也要确保它的Status字段是"chargeable"状态。如果源处于"pending"或"failed"状态,Stripe会拒绝扣款请求,也可能伴随参数错误的提示。可以加日志输出源的详细信息验证:

fmt.Printf("目标源详情:%+v\n", sc.Sources.Data[1])

4. 排查SDK版本兼容性

不同版本的Stripe Go SDK在参数校验逻辑上可能有差异,旧版本可能对Customer和Source的绑定要求更严格。建议确认你使用的SDK是最新稳定版,避免版本兼容问题。

另外你提到用令牌可以正常扣款,是因为令牌是一次性支付凭证,而客户源是关联到客户的持久化凭证,两者的参数传递逻辑不同。绑定客户ID发起扣款是Stripe推荐的最佳实践,也能避免这类参数识别问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:04:37