如何在Stripe-Firebase扩展事件中执行自定义云函数实现订阅赠Token
实现订阅成功后分配Token余额的方案
核心思路
通过Eventarc监听Stripe订阅付款成功事件,触发Cloud Function完成Token余额的计算与分配,全程依托Firebase生态内的工具实现,无需额外第三方服务。
步骤分解
确认Eventarc与Stripe事件配置
Firebase Stripe订阅扩展默认会将关键事件(如发票支付成功invoice.paid)推送至Eventarc。先确保你的Firebase项目已启用Eventarc,且Stripe扩展的事件通知处于开启状态(扩展配置页可查看/调整)。编写Cloud Function处理事件
创建一个Eventarc触发的Cloud Function,监听Stripe的invoice.paid事件(对应Firebase扩展推送的事件类型为firebase.extensions.stripe-subscriptions.v1.invoicePaid)。函数核心逻辑:- 解析事件中的发票数据,提取订阅金额(注意Stripe返回金额为分单位,5美元对应500,19美元对应1900)
- 通过Stripe客户ID关联到Firebase用户UID(Firebase Stripe扩展会在
customers集合中存储stripeId与uid的映射) - 根据金额规则计算应分配的Token,更新用户的Token余额存储(建议存在Firestore的
users集合或独立tokenBalances集合)
示例代码(Node.js):
const functions = require("firebase-functions"); const admin = require("firebase-admin"); admin.initializeApp(); exports.allocateTokensOnSubscription = functions.eventarc.onCustomEventPublished( "firebase.extensions.stripe-subscriptions.v1.invoicePaid", async (event) => { const invoice = event.data.payload.data.object; const invoiceId = invoice.id; const amountDue = invoice.amount_due; const stripeCustomerId = invoice.customer; // 幂等性检查:避免重复处理同一发票 const processedInvoicesRef = admin.firestore().collection("processedInvoices").doc(invoiceId); const processedDoc = await processedInvoicesRef.get(); if (processedDoc.exists) { functions.logger.info(`Invoice ${invoiceId} already processed`); return null; } // 关联Firebase用户UID const customerDoc = await admin.firestore().collection("customers").where("stripeId", "==", stripeCustomerId).get(); if (customerDoc.empty) { functions.logger.error(`No Firebase user found for Stripe customer ${stripeCustomerId}`); return null; } const userId = customerDoc.docs[0].data().uid; // 计算Token额度 let tokensToAdd = 0; if (amountDue === 500) { tokensToAdd = 2000; } else if (amountDue === 1900) { tokensToAdd = 50000; } else { functions.logger.warn(`Unrecognized subscription amount: ${amountDue}`); return null; } // 更新用户Token余额 const userTokenRef = admin.firestore().collection("users").doc(userId); await userTokenRef.set( { tokenBalance: admin.firestore.FieldValue.increment(tokensToAdd) }, { merge: true } ); // 标记发票已处理 await processedInvoicesRef.set({ processedAt: admin.firestore.Timestamp.now() }); functions.logger.info(`Allocated ${tokensToAdd} tokens to user ${userId} for invoice ${invoiceId}`); return null; } );部署与测试
- 部署函数:运行
firebase deploy --only functions - 测试:使用Stripe测试卡片创建对应金额的订阅,触发付款成功事件后,检查Firestore中用户的Token余额是否正确更新
- 部署函数:运行
关键注意事项
- 幂等性处理:必须记录已处理的发票ID,防止Stripe重复推送事件导致Token重复分配
- 金额单位:Stripe返回的金额以分为单位,需注意转换匹配
- 错误处理:添加日志记录异常情况,便于排查问题
内容的提问来源于stack exchange,提问作者SkyRar
相关产品推荐
相关产品推荐

