Firebase 支持哪些 payment gateways?
结论
Firebase 不是支付网关,不能直接处理银行卡或 PayPal 等付款。它提供的主要是身份认证、数据库、云函数和托管等后端能力。
开发时,可以将 Firebase 与第三方支付服务配合使用,例如:
- Stripe
- PayPal
- Adyen
- Braintree
- Square
- 支付宝、微信支付等提供服务端 API 的支付平台
- Apple App Store 和 Google Play 的应用内购买系统
Stripe 与 Firebase 的集成资料和现成方案比较多。接入其他支付网关时,通常需要使用 Cloud Functions 或独立后端。哪些平台可用,还要看商户注册地区、用户所在地、结算币种和业务类型。
Firebase 在支付流程中的作用
Firebase 通常负责支付流程中的后端辅助工作,不直接处理资金。一个常见流程是:
- Firebase Authentication 识别当前用户。
- 客户端向 Cloud Functions 请求创建订单。
- Cloud Functions 调用支付网关的服务端 API。
- 支付网关返回支付页面、支付令牌或客户端密钥。
- 用户在支付网关提供的安全界面中付款。
- 支付网关通过 Webhook 将支付结果通知服务器。
- Cloud Functions 验证通知,再把订单状态写入 Cloud Firestore。
- Firebase Security Rules 限制用户只能读取自己的订单。
这样可以避免将支付平台密钥放在客户端,也能防止客户端擅自修改订单金额或伪造支付结果。
以 Stripe 为例的基本接入方式
下面的示例展示了如何通过 Cloud Functions 创建 Stripe Checkout Session。实际接入时,需要按照当前 Firebase Functions SDK 和 Stripe SDK 的官方文档调整初始化方式及部署配置。
const { onCall, HttpsError } = require("firebase-functions/v2/https");
const { defineSecret } = require("firebase-functions/params");
const Stripe = require("stripe");
const stripeSecretKey = defineSecret("STRIPE_SECRET_KEY");
exports.createCheckoutSession = onCall(
{ secrets: [stripeSecretKey] },
async (request) => {
if (!request.auth) {
throw new HttpsError("unauthenticated", "User must be signed in.");
}
const stripe = new Stripe(stripeSecretKey.value());
// 商品和金额应从可信数据库读取,不能直接相信客户端提交的数据。
const session = await stripe.checkout.sessions.create({
mode: "payment",
line_items: [
{
price: "price_xxxxxxxxxxxxx",
quantity: 1,
},
],
success_url: "https://example.com/payment/success?session_id={CHECKOUT_SESSION_ID}",
cancel_url: "https://example.com/payment/cancel",
client_reference_id: request.auth.uid,
metadata: {
firebaseUid: request.auth.uid,
},
});
return {
sessionId: session.id,
url: session.url,
};
}
);
客户端登录 Firebase 后,可以调用这个 Callable Function:
import { getFunctions, httpsCallable } from "firebase/functions";
const functions = getFunctions();
const createCheckoutSession = httpsCallable(
functions,
"createCheckoutSession"
);
const result = await createCheckoutSession();
window.location.href = result.data.url;
客户端不应传入最终支付金额。更稳妥的做法是只提交商品 ID,再由 Cloud Functions 从 Firestore 或其他可信数据源查询价格。
必须使用 Webhook 确认付款
用户进入成功页面,只能说明浏览器完成了跳转,不能证明款项已经支付。订单状态必须以通过签名验证的支付网关 Webhook 事件为准。
const { onRequest } = require("firebase-functions/v2/https");
const { defineSecret } = require("firebase-functions/params");
const admin = require("firebase-admin");
const Stripe = require("stripe");
admin.initializeApp();
const stripeSecretKey = defineSecret("STRIPE_SECRET_KEY");
const stripeWebhookSecret = defineSecret("STRIPE_WEBHOOK_SECRET");
exports.stripeWebhook = onRequest(
{
secrets: [stripeSecretKey, stripeWebhookSecret],
},
async (req, res) => {
const stripe = new Stripe(stripeSecretKey.value());
const signature = req.headers["stripe-signature"];
let event;
try {
event = stripe.webhooks.constructEvent(
req.rawBody,
signature,
stripeWebhookSecret.value()
);
} catch (error) {
res.status(400).send(`Webhook Error: ${error.message}`);
return;
}
if (event.type === "checkout.session.completed") {
const session = event.data.object;
const uid = session.metadata?.firebaseUid;
if (uid) {
await admin.firestore()
.collection("payments")
.doc(session.id)
.set(
{
uid,
status: "paid",
paymentStatus: session.payment_status,
updatedAt: admin.firestore.FieldValue.serverTimestamp(),
},
{ merge: true }
);
}
}
res.status(200).send("ok");
}
);
生产环境还要保存支付平台的事件 ID,并做好幂等处理。否则,同一个 Webhook 被重复投递时,可能造成重复发货或重复增加用户权益。
使用 Firebase Extension
Firebase 生态中可能有由 Firebase 或合作方维护的支付相关 Extension,例如用于连接 Stripe 客户、订阅和 Firestore 数据的扩展。
Extension 能减少订阅同步和 Webhook 处理等重复代码,但它并不意味着 Firebase 自己提供收款服务。安装前需要确认:
- 扩展目前是否仍在维护
- 支持一次性支付、订阅,还是两者都支持
- 使用哪些 Firestore 集合和字段
- 会部署哪些 Cloud Functions
- 会产生哪些 Firebase 和支付平台费用
- 是否符合所在地区及业务类型的要求
扩展的名称、配置项和支持范围都可能变化,应以安装时显示的官方说明为准。
PayPal、支付宝和微信支付如何接入
这些平台的接入流程与 Stripe 大致相同:
- 客户端向 Cloud Functions 提交商品或订单标识。
- Cloud Functions 从可信数据源计算价格。
- Cloud Functions 使用服务端凭据调用支付平台 API。
- 客户端完成授权或跳转支付。
- 支付平台向 Cloud Functions 的 HTTPS 地址发送异步通知。
- 服务端验证签名,并主动查询订单状态。
- 确认支付成功后更新 Firestore。
只要支付平台提供服务端 API、签名验证和异步通知机制,原则上就可以与 Firebase 配合使用。有些平台会要求固定出口 IP、特定运行环境、证书文件或区域部署。遇到这些限制时,可能需要改用 Cloud Run 或独立服务器,不能只依赖 Cloud Functions。
移动应用需要注意商店支付规则
如果应用销售数字内容、会员功能、虚拟物品或应用内服务,iOS 和 Android 可能要求使用各自的应用内购买系统:
- iOS:StoreKit / In-App Purchase
- Android:Google Play Billing
即使技术上能够接入 Stripe 或其他支付网关,也不能因此直接绕过应用商店的支付要求。实体商品、线下服务等场景可能适用不同规则。相关要求会随地区、应用类别和商店政策变化,上线前应核对 Apple App Store 与 Google Play 的最新规定。
Firebase 可以保存购买状态、处理服务端通知并授予用户权益,但交易本身仍由 Apple 或 Google 的支付系统完成。
安全与成本注意事项
- 不要将支付网关的 Secret Key、私钥或 Webhook Secret 写入前端代码。
- 不要信任客户端提交的金额、折扣、币种或”支付成功”状态。
- Webhook 必须验证签名,并根据事件 ID 做幂等处理。
- 发货或开通会员前,应检查订单金额、币种、商品和支付状态。
- Firestore Security Rules 不能代替服务端支付验证。
- 支付数据应尽量通过 Admin SDK 写入,客户端只保留必要的读取权限。
- 不要在 Firestore 中保存完整银行卡号、CVV 等敏感卡片信息。
- 退款、拒付、订阅续费失败和订阅取消也要通过 Webhook 同步。
- 除支付网关手续费外,还要计算 Cloud Functions、Cloud Run、Firestore、网络流量和日志产生的费用。
- 税费、发票、身份验证和支付合规要求取决于业务所在地及支付服务商的规则。
选择 Firebase 不会将应用限制在某一个 payment gateway 上。准确地说,Firebase 不负责收款,但可以作为应用后端,与提供服务端 API 的支付平台集成。选型时,需要比较目标地区、支付方式、应用商店规则、订阅需求、合规要求和总体成本。
备注:内容仅供参考。
