运行 使用 Stripe 的订阅 Firebase 扩展向客户收费时的功能

Run Function when a Customer is charged using Stripe's Subscription Firebase Extension

每当用户通过 Stripe 的订阅扩展收费时,我都想 运行 一个 Firebase 云函数。该扩展程序是否会生成任何可触发云功能的事件,例如写入 Firestore?

我的方案是,每当用户成功收费时,我想在 Orders 集合中生成一个引用相应 User 文档的新文档。

不幸的是,扩展程序似乎无法处理正在进行的付款事件:https://github.com/stripe/stripe-firebase-extensions/blob/master/firestore-stripe-subscriptions/functions/src/index.ts#L419-L432

您需要修改该代码以包含可能的 invoice.payment_succeeded - 然后适当地处理 - 或者自己编写一个云函数来处理它(类似于此处显示的内容)。

我可以通过从 Stripe 的 Firebase 扩展的官方仓库借用一些代码来自己解决这个问题:https://github.com/stripe/stripe-firebase-extensions/blob/next/firestore-stripe-subscriptions/functions/src/index.ts

我创建了自己的 Firebase 函数并将其命名为 handleInvoiceWebhook,它验证并构建了 Stripe Invoice object,将其映射到我使用我关心的字段创建的自定义 Invoice 接口,然后保存invoices collection.

export const handleInvoiceWebhook = functions.https.onRequest(
  async (req: functions.https.Request, resp) => {
    let event: Stripe.Event;
    try {
      event = stripe.webhooks.constructEvent(
        req.rawBody,
        req.headers['stripe-signature'] || '',
        functions.config().stripe.secret
      );
    } catch (error) {
      resp.status(401).send('Webhook Error: Invalid Secret');
      return;
    }
    const invoice = event.data.object as Stripe.Invoice;
    const customerId= invoice.customer as string;

    await insertInvoiceRecord(invoice, customerId);
    resp.status(200).send(invoice.id);
  }
);

/**
 * Create an Invoice record in Firestore when a customer's monthly subscription payment succeeds.
 */
const insertInvoiceRecord = async (
  invoice: Stripe.Invoice,
  customerId: string
): Promise<void> => {
  // Invoice is an interface with only fields I care about
  const invoiceData: Invoice = {
    invoiceId: invoice.id,
    ...map invoice data here
  };
  await admin
    .firestore()
    .collection('invoices')
    .doc(invoice.id)
    .set(invoiceData);
};

部署后,我转到 Stripe 开发人员仪表板 (https://dashboard.stripe.com/test/webhooks) 并添加了一个新的 Webhook 监听事件类型 invoice.payment_succeeded 并且 url 是我的 Firebase 函数刚做的。

注意:我必须使用以下命令部署我的 Stripe API 密钥和 Webhook Secret 作为我的 Firebase 函数的环境变量:firebase functions:config:set stripe.key="sk_test_123" stripe.secret="whsec_456"