问题描述
每当 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 对象,将其映射到我使用我关心的字段创建的自定义 Invoice 界面,然后将其保存到 {{1 }} 集合。
invoices
部署后,我转到了 Stripe 开发人员仪表板 (https://dashboard.stripe.com/test/webhooks) 并添加了一个新的 Webhook,侦听事件类型 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);
};
,invoice.payment_succeeded
是我刚刚创建的 Firebase 函数.
注意:我必须使用以下命令将 Stripe API 密钥和 Webhook Secret 部署为 Firebase 函数的环境变量:url