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

Stripe订阅创建时将client_reference_id写入Firestore的问题

解决方案

1. 核心思路

从Stripe订阅创建的Webhook事件中精准提取client_reference_id,仅将该字段写入Firestore,替代原有存储整个原始事件数据的逻辑。

2. 修改后的Firebase Cloud Functions代码

假设你原本监听的是customer.subscription.created事件,以下是调整后的代码:

const functions = require("firebase-functions");
const admin = require("firebase-admin");
const stripe = require("stripe")(functions.config().stripe.secret);

admin.initializeApp();

exports.handleStripeWebhook = functions.https.onRequest(async (req, res) => {
  const sig = req.headers["stripe-signature"];
  let event;

  try {
    event = stripe.webhooks.constructEvent(
      req.rawBody,
      sig,
      functions.config().stripe.webhook_secret
    );
  } catch (err) {
    res.status(400).send(`Webhook Error: ${err.message}`);
    return;
  }

  if (event.type === "customer.subscription.created") {
    const subscription = event.data.object;
    let clientReferenceId;

    // 优先从订阅的metadata提取(推荐:创建支付链接时同步该字段到订阅metadata)
    if (subscription.metadata?.client_reference_id) {
      clientReferenceId = subscription.metadata.client_reference_id;
    }
    // 备选:从关联的Checkout Session中获取(需额外调用Stripe API)
    else if (subscription.checkout_session) {
      const checkoutSession = await stripe.checkout.sessions.retrieve(subscription.checkout_session);
      clientReferenceId = checkoutSession.client_reference_id;
    }

    if (clientReferenceId) {
      // 仅存储client_reference_id到Firestore
      await admin.firestore()
        .collection("subscriptions")
        .doc(subscription.id)
        .set({ client_reference_id: clientReferenceId });
      functions.logger.info(`已存储client_reference_id: ${clientReferenceId},对应订阅ID: ${subscription.id}`);
    } else {
      functions.logger.warn(`未找到订阅${subscription.id}对应的client_reference_id`);
    }

    res.json({ received: true });
  }
});

3. 关键细节说明

  • 高效提取方式:如果创建支付链接(Checkout Session)时,同步把client_reference_id写入subscription_data.metadata(代码示例如下),可以直接从订阅对象的metadata中提取,无需额外调用Stripe API,提升性能。
  • 容错处理:添加日志记录,方便排查未找到目标ID的异常情况。
  • 存储结构简化:Firestore文档仅保留client_reference_id字段,完全符合需求。

补充:创建支付链接时同步metadata的代码示例

const session = await stripe.checkout.sessions.create({
  payment_method_types: ["card"],
  line_items: [{ price: "price_xxx", quantity: 1 }],
  mode: "subscription",
  success_url: "https://your-domain.com/success",
  cancel_url: "https://your-domain.com/cancel",
  client_reference_id: "用户自定义ID",
  // 将client_reference_id同步到订阅的metadata中
  subscription_data: {
    metadata: {
      client_reference_id: "用户自定义ID"
    }
  }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 22:12:48