You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何提取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层级时无法获取自定义的商品名、图片等字段
修复方案
  1. 调整检索Checkout Session的expand参数,补充展开line_items.data.price层级,获取嵌套的价格、商品信息
  2. 遍历session.line_items.data数组,仅提取需要的商品标题、单价、数量、图片字段,过滤冗余数据
  3. 补充事件类型判断,仅在checkout.session.completed(支付完成)事件触发时执行入库逻辑,避免其他Stripe事件触发时结构不匹配报错
  4. 修正原代码中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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 04:57:07