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

使用Stripe时出现TypeError:无法读取undefined的map属性

问题修复:单个商品结账显示所有商品+TypeError报错

问题根源

  1. TypeError: Cannot read properties of undefined (reading 'map'):

    • 服务器端Stripe会话创建的字段名拼写错误,line_item应为复数line_items
    • 未对req.body.items做空值判断,前端未正确传值时会触发map调用失败
    • 错误将Stripe的priceId赋值给unit_amount(unit_amount需传入金额分数值,而非price ID)
  2. 结账显示所有商品:

    • 前端checkout.js硬编码了所有商品ID到请求体,未仅传递选中的单个商品

修复步骤及代码修改

1. 修正server.js代码

// require("dotenv").config()

// This is your test secret API key.
const stripe = require('stripe')('sk_test_XXXXXXX')

const express = require('express')
const app = express()
app.use(express.static('public'))
app.use(express.json())

const YOUR_DOMAIN = 'http://localhost:4242';

const storeItems = new Map([
   [1, { priceId: 'price_XXXXXX', name: "Black Sweatsuit"}],
   [2, { priceId: 'price_XXXXXX', name: "Grey Sweatsuit"}] ,
   [3, { priceId: 'price_XXXXXX', name: "Red Sweatsuit"}],
   [4, { priceId: 'price_XXXXXX', name: "Blue Sweatsuit"}],
   [5, { priceId: 'price_XXXXXX', name: "Black T-Shirt"}],
   [6, { priceId: 'price_XXXXXX', name: "Blue T-Shirt"}],
   [7, { priceId: 'price_XXXXXX', name: "Purple T-Shirt"}],
])

app.post('/create-checkout-session', async (req, res) => {
  try {
    // 空值判断,避免map调用失败
    const items = req.body.items || [];
    if (items.length === 0) {
      return res.status(400).json({ error: '未选择任何商品' });
    }

    const session = await stripe.checkout.sessions.create({
      payment_method_types: ['card'],
      mode: 'payment',
      // 修正字段名为line_items(复数)
      line_items: items.map(item => {
        const storeItem = storeItems.get(item.id)
        if (!storeItem) {
          throw new Error(`商品ID ${item.id} 不存在`);
        }
        // 直接使用Stripe已创建的price ID
        return {
          price: storeItem.priceId,
          quantity: item.quantity || 1
        }
      }),
      success_url:`${YOUR_DOMAIN}/success.html`,
      cancel_url: `${YOUR_DOMAIN}/cancel.html`,
      automatic_tax: {enabled: true},    
    })
    res.json({ url: session.url})
  } catch (e) {
    res.status(500).json({ error: e.message })
  }
})

app.listen(4242, () => console.log('Running on port 4242'));

2. 修正checkout.js代码(支持单个商品选择)

先修改shop.html中的商品按钮,为每个按钮添加data-id属性:

<!-- 单个商品购买按钮示例 -->
<button class="checkout-button" data-id="1">购买 Black Sweatsuit</button>
<button class="checkout-button" data-id="2">购买 Grey Sweatsuit</button>
<!-- 其他商品按钮同理 -->

再修改checkout.js:

// 给所有结账按钮绑定点击事件
document.querySelectorAll(".checkout-button").forEach(button => {
  button.addEventListener("click", () => {
    // 获取当前按钮对应的商品ID
    const productId = parseInt(button.dataset.id);
    
    fetch('/create-checkout-session', {
      method: 'POST',
      headers: {
        "Content-Type": "application/json"
      },
      body: JSON.stringify({
        // 仅传递选中的单个商品
        items: [{ id: productId, quantity: 1 }]
      }),
    })
    .then(res => {
      if (res.ok) return res.json()
      return res.json().then(json => Promise.reject(json))
    })
    .then(({ url }) => {
      window.location = url
    })
    .catch(e => {
      console.error(e.error)
    })
  })
})

关键修复点说明

  • 字段名修正:Stripe Checkout会话要求商品列表字段为line_items,单数字段会导致API无法识别
  • 空值处理:增加req.body.items的空值判断,避免undefined调用map方法
  • 商品传递逻辑:通过按钮data-id获取选中商品ID,仅传递单个商品数据
  • Price ID使用:直接调用Stripe后台创建的priceId,避免错误赋值unit_amount

内容的提问来源于stack exchange,提问作者user16147870

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 22:55:19