Firebase云函数处理Stripe Webhook时出现TypeError问题求助
解决Firebase云函数处理Stripe Webhook时的
stripe-signature未定义错误 错误原因
报错TypeError: Cannot read properties of undefined (reading 'stripe-signature')说明请求头中不存在stripe-signature字段,或Firebase HTTP函数的默认配置导致无法正确获取请求头/原始请求体。
解决方案
1. 配置Firebase函数保留原始请求体
Firebase的https.onRequest默认会自动解析JSON请求体,这会导致request.rawBody无法获取Stripe签名验证所需的原始未解析数据,同时可能影响请求头的读取。需要在函数配置中开启rawBody: true:
exports.updateTokenBalanceOnPurchase = functions.https.onRequest({ rawBody: true }, async (request, response) => { // 原有代码逻辑保持不变 });
2. 增加签名头存在性校验
在尝试获取签名头后立即校验是否存在,避免后续逻辑抛出未定义错误:
exports.updateTokenBalanceOnPurchase = functions.https.onRequest({ rawBody: true }, async (request, response) => { let sig = request.headers["stripe-signature"]; // 新增校验逻辑 if (!sig) { return response.status(400).send("Missing stripe-signature header"); } try { let event = stripe.webhooks.constructEvent( request.rawBody, sig, endpointSecret ); // 原有事件处理逻辑 if (event.type === "checkout.session.completed") { const session = event.data.object; const uid = session.client_reference_id; const priceId = session.display_items[0].custom.price.id; await updateUserTokensBalance(uid, priceId); } return response.json({ received: true }); } catch (err) { console.error(err); return response.status(err.statusCode || 500).send(err.message); } });
3. 验证Stripe Webhook配置
- 确认Stripe Dashboard中Webhook的端点URL与Firebase函数的部署URL完全一致
- 确认Webhook已启用
checkout.session.completed事件类型 - 确认使用的
STRIPE_WEBHOOK_SECRET是Stripe Dashboard中生成的Webhook签名密钥(而非Stripe API密钥) - 确认Firebase环境变量已正确设置
STRIPE_WEBHOOK_SECRET(可通过firebase functions:config:get命令检查)
4. 潜在代码优化(避免后续错误)
当前代码中session.display_items[0].custom.price.id存在结构风险,若display_items为空或结构不符会抛出错误,建议增加校验:
if (event.type === "checkout.session.completed") { const session = event.data.object; const uid = session.client_reference_id; // 校验display_items结构合法性 if (!session.display_items || session.display_items.length === 0 || !session.display_items[0]?.custom?.price?.id) { console.error("Invalid session display items structure"); return response.json({ received: true }); // 返回成功避免Stripe重复重试 } const priceId = session.display_items[0].custom.price.id; await updateUserTokensBalance(uid, priceId); }
内容的提问来源于stack exchange,提问作者Tui
相关产品推荐
相关产品推荐

