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

React-Native集成Stripe时Firebase云函数报400错误如何修复?

React-Native 集成 Firebase Cloud Functions + Stripe 400错误排查方案

你的报错是云函数类型不匹配、参数写法错误、请求逻辑错误叠加导致的,按以下方向逐一排查修正即可:

  • 云函数类型和调用方式完全不匹配:你定义云函数用的是onCall(Firebase专属可调用函数),但前端用fetch发普通HTTP POST请求,onCall类型函数要求请求带固定格式的鉴权头、结构化请求体,普通fetch请求不符合协议要求,会直接触发Request is missing body/Invalid request的400错误。
  • Stripe SDK参数写法错误:调用stripe.paymentIntents.create时多余套了一层data字段,Stripe Node SDK要求直接传入配置对象,外层包data会导致参数无法被正确识别。
  • onCall函数返回逻辑错误:onCall函数的第二个参数是上下文对象,不是HTTP响应对象,不需要也不能用response.json()返回结果,直接return目标对象即可。
  • 前端请求逻辑错误:一是请求路径和云函数导出名不匹配,你导出的函数名是payWithStripe,前端请求的路径是/create-payment-intent,路径根本对应不上;二是POST请求没有传body字段,就算是普通HTTP接口也会触发缺请求体报错。

修正代码(二选一即可,新手推荐选onRequest方案,逻辑更直观)

方案1:使用onRequest类型云函数(适配普通fetch调用)

云函数index.js代码

// 提前初始化Stripe,替换为你自己的Stripe服务端秘钥
const stripe = require('stripe')('你的Stripe服务端秘钥');
// 导出名称和前端请求路径保持一致
exports.createPaymentIntent = functions.https.onRequest(async (req, res) => {
  // 配置跨域,否则React-Native端请求会被拦截
  res.set('Access-Control-Allow-Origin', '*');
  res.set('Access-Control-Allow-Headers', 'Content-Type');
  // 处理预检请求
  if (req.method === 'OPTIONS') {
    res.status(204).send('');
    return;
  }

  try {
    const paymentIntent = await stripe.paymentIntents.create({
      amount: 100, // Stripe金额按最小货币单位计算,100对应1美元
      currency: "usd",
      payment_method_types: ["card"]
    });

    res.json({
      clientSecret: paymentIntent.client_secret,
    })
  } catch (e) {
    console.log(e.message);
    res.status(400).json({ error: e.message });
  }
})

对应前端请求代码

const fetchPaymentIntentClientSecret = async () => {
    const response = await fetch(`${FUNCTION_URL}/createPaymentIntent`, {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
        },
        // POST请求即使不传参数也要传空body,避免触发缺body报错
        body: JSON.stringify({})
    });

    if (!response.ok) {
      const errRes = await response.json();
      return { clientSecret: null, error: errRes.error };
    }

    const { clientSecret, error } = await response.json();
    return { clientSecret, error };
}

方案2:使用onCall可调用函数(需要搭配Firebase SDK调用)

云函数index.js代码

const stripe = require('stripe')('你的Stripe服务端秘钥');
exports.payWithStripe = functions.https.onCall(async (data, context) => {
  try {
    const paymentIntent = await stripe.paymentIntents.create({
      amount: 100,
      currency: "usd",
      payment_method_types: ["card"]
    });
    // onCall函数直接return结果即可,不需要操作响应对象
    return {
      clientSecret: paymentIntent.client_secret,
    }
  } catch (e) {
    console.log(e.message);
    // onCall错误需要按官方指定格式抛出
    throw new functions.https.HttpsError('internal', e.message);
  }
})

对应前端请求代码

import { getFunctions, httpsCallable } from "firebase/functions";
const functions = getFunctions();
const payWithStripeRequest = httpsCallable(functions, 'payWithStripe');

const fetchPaymentIntentClientSecret = async () => {
  try {
    const res = await payWithStripeRequest();
    return { clientSecret: res.data.clientSecret, error: null };
  } catch (e) {
    return { clientSecret: null, error: e.message };
  }
}

额外排查项

  • 确认FUNCTION_URL配置正确:本地调试要填对模拟器对应的端口,线上部署要填Firebase分配的云函数域名,不要漏写项目路径前缀。
  • 确认云函数环境配置的Stripe秘钥是服务端秘钥(以sk_开头),不要误填客户端公钥(以pk_开头)。
  • 云函数部署完成后等待1-2分钟再发起请求,刚部署完成的函数冷启动阶段可能偶发请求异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 00:42:31