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

Stripe支付状态始终为'requires_source'问题排查求助

问题分析与解决方案

核心问题定位

requires_source状态说明Stripe尚未获取到有效支付来源(如信用卡信息),同时Firebase Cloud Functions返回状态与Stripe实际事件不符,大概率是Webhook事件接收/解析错误或支付流程逻辑缺失导致。


分步排查与修复

1. 校验Stripe Webhook配置与签名验证

  • 确认Firebase Functions的Webhook端点已在Stripe Dashboard中正确配置,且启用payment_intent.succeeded、payment_intent.payment_failed等关键事件。
  • 必须通过Stripe签名验证确保事件合法性,避免伪造。Cloud Functions中示例代码:
    const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
    const endpointSecret = process.env.STRIPE_WEBHOOK_SECRET;
    const admin = require('firebase-admin');
    admin.initializeApp();
    
    exports.stripeWebhook = functions.https.onRequest(async (req, res) => {
      const sig = req.headers['stripe-signature'];
      let event;
      try {
        // 必须用rawBody解析,不能用req.body(Firebase默认会解析JSON,破坏签名验证)
        event = stripe.webhooks.constructEvent(req.rawBody, sig, endpointSecret);
      } catch (err) {
        return res.status(400).send(`Webhook Error: ${err.message}`);
      }
    
      // 打印日志排查实际接收的事件
      console.log(`事件类型: ${event.type}, 支付状态: ${event.data.object.status}`);
    
      switch (event.type) {
        case 'payment_intent.succeeded':
          const paymentIntent = event.data.object;
          // 支付成功后写入数据库
          await admin.database().ref(`payments/${paymentIntent.id}`).set({
            status: 'succeeded',
            amount: paymentIntent.amount,
            createdAt: paymentIntent.created
          });
          break;
        case 'payment_intent.payment_failed':
          const failedIntent = event.data.object;
          // 支付失败执行对应操作
          await admin.database().ref(`payments/${failedIntent.id}`).update({
            status: 'failed',
            errorMsg: failedIntent.last_payment_error?.message
          });
          break;
        default:
          console.log(`未处理事件类型: ${event.type}`);
      }
      res.json({received: true});
    });
    

2. 补全Flutter端支付来源绑定逻辑

requires_source状态的直接原因是Payment Intent未关联支付方式,Flutter端需确保确认支付时传入支付来源:

import 'package:stripe/stripe.dart';

// 创建支付方式
final paymentMethod = await Stripe.instance.createPaymentMethod(
  PaymentMethodParams.card(
    card: CardDetails(
      number: '4242424242424242', // Stripe测试卡号
      expMonth: 12,
      expYear: 2025,
      cvc: '123',
    ),
  ),
);

// 确认支付,传入支付方式ID
final confirmResponse = await Stripe.instance.confirmPaymentIntent(
  clientSecret: '从后端获取的Payment Intent Client Secret',
  data: PaymentIntentConfirmData(
    paymentMethodId: paymentMethod.id,
  ),
);

3. 修正后端状态获取逻辑

  • 禁止依赖前端传递的支付状态,必须以Stripe Webhook事件中event.data.object.status为准。
  • 检查Cloud Functions代码,确保没有错误使用前端参数覆盖Stripe事件返回的状态。

4. 校验Payment Intent创建参数

创建Payment Intent时需指定必要参数,避免因配置缺失导致状态异常:

const paymentIntent = await stripe.paymentIntents.create({
  amount: 1000, // 单位:分,对应10美元
  currency: 'usd',
  payment_method_types: ['card'],
  // 若不需要手动捕获,可省略capture_method,默认自动捕获
  capture_method: 'automatic'
});
// 返回clientSecret给前端用于支付确认
return {clientSecret: paymentIntent.client_secret};

额外排查点

  • 检查Stripe Dashboard的支付日志,查看Payment Intent的历史状态变化,确认是否存在失败的支付尝试。
  • 确保Firebase Functions的Node.js版本与Stripe SDK兼容(推荐Node.js 18+)。
  • 用Stripe测试卡号模拟场景:4242 4242 4242 4242(成功支付)、4000 0000 0000 0002(支付失败)。

内容的提问来源于stack exchange,提问作者İsmail Ayberk Gün

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 17:45:46