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

Stripe PaymentIntent创建报错:Invalid integer: NaN 求助

问题

向Stripe的paymentIntents.create方法的amount参数传入数据时遇到以下问题:

  • 客户端向服务器发送price字段,控制台输出数据正确,typeof检测结果为number类型;
  • 运行应用时报错:UnhandledPromiseRejectionWarning: Error: Invalid integer: NaN;
  • 直接传入price字段时,报错:Error: Missing required param: amount。

相关代码

const express = require("express");
const app = express();
const { resolve } = require("path");
const stripe = require("stripe")(process.env.secret_key);

app.use(express.static("."));
app.use(express.json());

const calculateOrderAmount = price =>{
  const total = price * 100 
  return total
}

// An endpoint for your checkout
app.post("/payment-sheet", async (req, res) => {
  const price = req.body.price
  console.log(typeof calculateOrderAmount(price))
  
  const paymentIntent = await stripe.paymentIntents.create({
    amount: calculateOrderAmount(price),
    currency: "usd",
    automatic_payment_methods: {
      enabled: true,
    },
  });

  // Send the object keys to the client
  res.json({
    publishableKey: process.env.publishable_key,
    paymentIntent: paymentIntent.client_secret,
  });
});

app.listen(process.env.PORT, () =>
  console.log(`Node server listening on port ${process.env.PORT}!`)
);

问题分析与解决方法

核心问题

尽管你提到客户端发送的price是number类型,但实际传到服务器后可能存在隐式类型转换失败或参数未正确解析的情况,导致calculateOrderAmount(price)返回NaN,触发Stripe的报错。另外Stripe要求amount必须是正整数(对应货币最小单位,比如美元的分),直接传入浮点数形式的price会被判定为无效参数。

具体修复步骤

  1. 强制校验并转换price类型
    客户端传来的数据可能存在隐性问题(比如字符串形式的数字、NaN值),即使typeof显示number也不能完全保证有效性。接收参数时先做校验:

    const price = Number(req.body.price);
    // 校验不通过直接返回错误
    if (isNaN(price) || price <= 0) {
      return res.status(400).json({ error: "Invalid price value" });
    }
    
  2. 确保amount为整数
    浮点数相乘易出现精度误差(比如0.1 * 100 = 10.000000000000002),需用Math.round()确保结果是整数:

    const calculateOrderAmount = price => {
      return Math.round(price * 100);
    };
    
  3. 捕获异步错误
    原代码未处理stripe.paymentIntents.create的异步异常,导致出现UnhandledPromiseRejectionWarning,用try/catch包裹处理:

    app.post("/payment-sheet", async (req, res) => {
      try {
        const price = Number(req.body.price);
        if (isNaN(price) || price <= 0) {
          return res.status(400).json({ error: "Invalid price value" });
        }
    
        const amount = calculateOrderAmount(price);
        const paymentIntent = await stripe.paymentIntents.create({
          amount: amount,
          currency: "usd",
          automatic_payment_methods: {
            enabled: true,
          },
        });
    
        res.json({
          publishableKey: process.env.publishable_key,
          paymentIntent: paymentIntent.client_secret,
        });
      } catch (error) {
        res.status(500).json({ error: error.message });
      }
    });
    
  4. 验证客户端请求格式
    确认客户端发送请求时,Content-Type设置为application/json,且请求体中的price为有效正数字(避免传空值、字符串或非数字内容)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 02:30:51