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

Google Cloud Function调用Stripe Checkout返回Bad Request问题求助

问题原因及解决方法

核心错误:混淆Firebase Callable函数与HTTP函数逻辑

你的代码使用了https.onCall(Callable函数),但错误地按照HTTP函数的方式处理请求(使用req, res参数、res.redirect跳转),这是触发400错误的直接原因。Callable函数有专属的参数规范和返回机制,不能套用HTTP响应逻辑。

具体问题点

  • Callable函数的回调参数应为(data, context),而非(req, res):data存储前端传入的参数,context包含请求上下文信息,用req会导致参数解析异常。
  • 冗余的Express中间件:Callable函数无需额外配置cors、express.json等中间件,Firebase Functions已内置处理相关逻辑,多余配置会干扰请求解析。
  • res.redirect()不适用:Callable函数需返回JSON对象,跳转逻辑应由前端完成,后端直接返回会话URL即可。
  • 硬编码业务参数:代码里固定了customer和price值,未使用前端传入的参数,会导致功能不符合预期。

修复后的代码

const functions = require('firebase-functions');
const stripe = require('stripe')(functions.config().stripe.secret_key);

exports.createStripeCheckout2 = functions.region('europe-west2').https.onCall(async (data, context) => {
  // 提取前端传入的参数
  const customerId = data.customerId;
  const priceId = data.priceId;
  const quantity = Number(data.students);

  // 校验必要参数(可选但推荐)
  if (!customerId || !priceId || isNaN(quantity)) {
    throw new functions.https.HttpsError('invalid-argument', '缺少必要参数或参数格式错误');
  }

  try {
    const session = await stripe.checkout.sessions.create({
      payment_method_types: ["card"],
      mode: 'subscription',
      allow_promotion_codes: true,
      customer: customerId,  
      line_items: [
        {
          price: priceId,
          quantity: quantity,
        },
      ],
      success_url: `https://learning-platform-835f9.web.app/`,
      cancel_url: `https://learning-platform-835f9.web.app/`,
    });

    // 返回会话URL给前端,由前端处理跳转
    return { sessionUrl: session.url };
  } catch (error) {
    // 标准化错误返回,便于前端处理
    throw new functions.https.HttpsError('internal', '创建结账会话失败', error.message);
  }
});

前端调用示例(JavaScript)

需使用Firebase SDK的Callable函数方式调用:

import { getFunctions, httpsCallable } from "firebase/functions";

const functions = getFunctions();
const createCheckout = httpsCallable(functions, 'createStripeCheckout2');

// 发起调用并处理结果
createCheckout({
  customerId: '你的客户ID',
  priceId: '你的价格ID',
  students: 1
})
.then((result) => {
  const sessionUrl = result.data.sessionUrl;
  window.location.href = sessionUrl; // 跳转到Stripe结账页
})
.catch((error) => {
  console.error('调用失败:', error);
});

额外排查步骤

  1. 验证Stripe密钥配置:运行firebase functions:config:get,确认stripe.secret_key存在且有效。
  2. 检查Stripe资源有效性:确认customerId和priceId在Stripe Dashboard中存在,且价格类型与mode: 'subscription'匹配(必须是订阅型价格)。
  3. 查看函数日志:执行firebase functions:log获取详细错误信息,定位参数或Stripe API调用的具体问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 14:20:22