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

Flutter Stripe网页端支付出现CORS错误,求解决方案

解决Flutter网页端Stripe支付的CORS报错问题

核心原因

浏览器的同源策略限制了跨域请求,你的Firebase Cloud Functions未返回正确的CORS响应头,导致网页端请求被拦截。而Android/iOS端不受浏览器同源策略约束,因此能正常运行支付功能。

具体修复方案

1. 为Cloud Functions添加CORS配置

有两种方式实现,任选其一即可:

方式一:手动添加CORS响应头

修改index.js,在函数开头处理预检请求并添加CORS头:

const functions = require("firebase-functions");
const stripe = require("stripe")("sk_...");

exports.stripePaymentIntentRequest = functions.https.onRequest(async (req, res) => {
    // 配置CORS头(生产环境建议替换为你的网页域名,如https://your-app.web.app)
    res.set('Access-Control-Allow-Origin', '*');
    res.set('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
    res.set('Access-Control-Allow-Headers', 'Content-Type');

    // 处理浏览器OPTIONS预检请求
    if (req.method === 'OPTIONS') {
        res.status(204).send('');
        return;
    }

    try {
        let customerId;

        const customerList = await stripe.customers.list({
            email: req.body.email,
            limit: 1
        });

        if (customerList.data.length !== 0) {
            customerId = customerList.data[0].id;
        } else {
            const customer = await stripe.customers.create({
                email: req.body.email
            });
            // 修复原代码错误:Stripe返回的customer是直接对象,无需.data.id
            customerId = customer.id;
        }

        const ephemeralKey = await stripe.ephemeralKeys.create(
            { customer: customerId },
            { apiVersion: '2020-08-27' }
        );

        const paymentIntent = await stripe.paymentIntents.create({
            amount: parseInt(req.body.amount),
            currency: 'eur',
            customer: customerId,
        });

        res.status(200).send({
            paymentIntent: paymentIntent.client_secret,
            ephemeralKey: ephemeralKey.secret,
            customer: customerId,
            success: true,
        });

    } catch (error) {
        // 404状态码不合适,改用400表示请求/服务异常
        res.status(400).send({ success: false, error: error.message });
    }
});

方式二:使用cors库简化配置

先安装依赖:

npm install cors

再修改代码:

const functions = require("firebase-functions");
const stripe = require("stripe")("sk_...");
// 允许所有来源,生产环境可配置具体域名如{origin: "https://your-app.web.app"}
const cors = require("cors")({ origin: true });

exports.stripePaymentIntentRequest = functions.https.onRequest(async (req, res) => {
    // 通过cors中间件处理跨域
    cors(req, res, async () => {
        try {
            let customerId;

            const customerList = await stripe.customers.list({
                email: req.body.email,
                limit: 1
            });

            if (customerList.data.length !== 0) {
                customerId = customerList.data[0].id;
            } else {
                const customer = await stripe.customers.create({
                    email: req.body.email
                });
                customerId = customer.id;
            }

            const ephemeralKey = await stripe.ephemeralKeys.create(
                { customer: customerId },
                { apiVersion: '2020-08-27' }
            );

            const paymentIntent = await stripe.paymentIntents.create({
                amount: parseInt(req.body.amount),
                currency: 'eur',
                customer: customerId,
            });

            res.status(200).send({
                paymentIntent: paymentIntent.client_secret,
                ephemeralKey: ephemeralKey.secret,
                customer: customerId,
                success: true,
            });

        } catch (error) {
            res.status(400).send({ success: false, error: error.message });
        }
    });
});

2. 修复原代码中的潜在错误

原代码中customerId = customer.data.id是错误的,Stripe的customers.create接口直接返回客户对象,应改为customer.id,这个错误可能导致隐藏的运行异常。

3. 重新部署Cloud Functions

执行命令更新部署:

firebase deploy --only functions

生产环境安全优化

  • 不要用*作为Access-Control-Allow-Origin,替换为你的Flutter网页端实际域名
  • 将Stripe密钥存储在Firebase环境变量中,避免硬编码:
    firebase functions:config:set stripe.secret="sk_..."
    
    代码中用functions.config().stripe.secret获取密钥。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 14:40:24