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

iOS App集成Stripe调用requestPayment报source/customer缺失错误排查

Stripe支付报错「Must provide source or customer」问题定位与修复

核心问题根因

  • 报错Error: Must provide source or customer:前后端参数名不匹配,iOS端调用云函数时传的用户Stripe ID参数key是customerID,云函数makeCharge接口里取值用的key是customer_id,命名规则(驼峰/下划线)不一致,导致取到的customerID为undefined。
  • 硬编码customerID后报错「Cannot charge a customer that has no active card」:后端调用扣款接口时,没有传入用户在前端选中的支付方式ID,Stripe不知道要从该客户名下哪张卡扣款;如果硬编码的测试客户本身没绑定过支付方式,也会触发这个报错。
  • 真卡/测试卡提示「Your card was declined」:你当前使用的是旧版stripe.charges.create直接扣款逻辑,没有适配3DS安全验证,约旦地区发行的银行卡大多强制要求3DS验证,旧接口无法触发验证流程就会直接拒付,和区域准入规则无关,JOD是Stripe官方支持的结算货币。
  • 隐性笔误风险:你在用户创建触发器里写入Firestore的Stripe客户ID字段名是stripID(Stripe少拼了字母e),虽然当前前后端都用这个错名字段暂时能匹配,但后续维护很容易踩坑。
  • 逻辑漏洞:iOS端的didCreatePaymentResult回调里,没有把Stripe返回的支付方式ID传给后端,后端完全拿不到用户选的卡信息,自然无法完成扣款。

分步修复方案

1. 统一前后端参数命名

打开Firebase云函数index.js,把makeCharge和createEphemeralKey两个接口里取客户ID的代码,从:

const customerID = data.customer_id;

修改为和iOS端传参一致的key:

const customerID = data.customerID;

建议全链路统一参数命名规则,要么全用驼峰格式,要么全用下划线格式,避免跨端传参出现取值为空的问题。

2. 补全支付源参数传递

  • 首先修改iOS端didCreatePaymentResult回调的传参逻辑,把用户选中的支付方式ID一并传给云函数:
let data : [String : Any] = [
    "total" : StripeCart.total ,
    "customerID" : UserService.user.stripID ,
    "sourceId": paymentResult.sourceId, // 新增:用户选中的支付方式唯一标识
    "idempotency" : idempotency
]
  • 然后修改云函数makeCharge的扣款逻辑,传入支付源参数:
return stripe.charges.create({
    amount: total,
    currency: 'JOD',
    customer: customerID,
    source: data.sourceId // 新增:指定本次扣款使用的支付方式
}, {
    idempotency_key: idempotency
})

长期建议迁移到新版PaymentIntent API替代旧版Charges接口,可自动适配3DS验证流程,大幅降低约旦地区银行卡的拒付率。

3. 修正字段拼写(强烈建议)

把全链路的stripID字段统一修正为正确拼写stripeID:

  • 云函数createStripeCustomer里的Firestore更新代码改为:
return admin.firestore().collection('users').doc(data.id).update({ stripeID: customer.id })
  • iOS端用户模型取值、传参key同步修改为stripeID,云函数对应取值key同步调整,避免后续维护出现字段不匹配问题。

4. 支付测试注意事项

  • 流程调试阶段先用Stripe官方基础测试卡4242 4242 4242 4242,过期日期填未来任意年月,CVC填任意3位数字,先跑通完整支付流程再切换真实卡测试。
  • 真卡支付如果仍被拒,去Stripe后台查看具体拒付错误码,基本都是3DS验证未触发导致,迁移到PaymentIntent接口后可自动处理验证流程,解决绝大多数拒付问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 05:09:15