如何提取Stripe line_items的price_data写入Firestore
报错根因
session.line_items.price_data返回undefined由两点导致:
- Stripe的列表类返回结构为固定格式,
line_items根节点存放列表元信息,实际商品条目存放在session.line_items.data数组中,根节点不存在price_data属性 - 创建Checkout Session时传入的
price_data参数不会直接挂载在line_item条目上,而是嵌套在每个条目的price属性下,默认不展开price层级时无法获取自定义的商品名、图片等字段
修复方案
- 调整检索Checkout Session的
expand参数,补充展开line_items.data.price层级,获取嵌套的价格、商品信息 - 遍历
session.line_items.data数组,仅提取需要的商品标题、单价、数量、图片字段,过滤冗余数据 - 补充事件类型判断,仅在
checkout.session.completed(支付完成)事件触发时执行入库逻辑,避免其他Stripe事件触发时结构不匹配报错 - 修正原代码中
shppingInfo的拼写错误为shippingInfo,避免后续字段读取异常
修正后可运行代码
exports.stripeWebhook=functions.https.onRequest(async (req, res)=>{ const stripe = require("stripe")(functions.config().stripe.token); let event; try { const whSec=functions.config().stripe.payments_webhook_secret; event = stripe.webhooks.constructEvent( req.rawBody, req.headers["stripe-signature"], whSec, ); } catch (err) { console.error("Webhook signature verification failed.", err); return res.sendStatus(400); } // 仅处理支付完成事件 if (event.type !== 'checkout.session.completed') { return res.sendStatus(200); } const dataObject = event.data.object; // 补充展开price层级 const session = await stripe.checkout.sessions.retrieve(dataObject.id, { expand: ['line_items.data.price'] }); // 提取需要的订单商品字段 const orderItems = session.line_items.data.map(item => { const priceInfo = item.price; return { name: priceInfo.product_data.name, // 商品标题 unitPrice: priceInfo.unit_amount / 100, // 商品单价,转换为常规货币单位 quantity: item.quantity, // 购买数量 images: priceInfo.product_data.images || [] // 商品图片 } }); await admin.firestore().collection("customer").doc(String(dataObject.customer_email)).collection("order").doc().set({ checkoutSessionId: dataObject.id, paymentStatus: dataObject.payment_status, shippingInfo: dataObject.shipping, amountTotal: dataObject.amount_total/100, customerId: dataObject.customer, customerEmail: dataObject.customer_email, orderItems: orderItems, }); return res.sendStatus(200); });
补充说明
如果你创建Checkout Session时没有使用临时传入的price_data,而是用了提前在Stripe后台创建好的固定商品/价格,需要做两处调整:
- 将
expand参数改为['line_items.data.price.product'] - 提取字段时对应取
priceInfo.product.name、priceInfo.product.images即可,其他逻辑不变
内容的提问来源于stack exchange,提问作者Grace
相关产品推荐
相关产品推荐

