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

在Next.js中使用Stripe时始终返回undefined的问题排查

Next.js中Stripe产品列表返回undefined的问题解决

问题场景

你的配置和代码如下:

  • .env.local文件:
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY = pk_test_apikeycontinues
STRIPE_SECRET_KEY = sk_test_apikeycontinues
  • ./app/utils/stripe.js:
import Stripe from 'stripe';

export const stripe = Stripe(process.env.STRIPE_SECRET_KEY);
  • 首页代码(两种写法均返回undefined):
    第一种:
'use client'

import { stripe } from "./utils/stripe";

export default function Home({ products }) {
  console.log(products);
  
  return (
    <div>
      home
    </div>
  )
}

export async function getStaticProps() {
  const inventory = await stripe.products.list({
    limit: 5,
  });
  
  return {
    props: {
      products: inventory,
    },
  };
}

第二种(直接写入密钥):

'use client'

import Stripe from 'stripe';

export const stripe = Stripe("sk_test_apikeycontinues");

export default function Home({ products }) {
  console.log(products);
  
  return (
    <div>
      home
    </div>
  )
}

export async function getStaticProps() {
  const inventory = await stripe.products.list({
    limit: 5,
  });
  
  return {
    props: {
      products: inventory,
    },
  };
}

Stripe测试环境已有库存,但控制台始终打印undefined。

核心错误原因

  1. 'use client'导致getStaticProps失效:在Next.js 13+的App Router中,添加'use client'指令会将整个组件标记为客户端组件,而getStaticProps仅能在服务器组件中运行,客户端组件中的getStaticProps不会被执行,因此products参数始终为undefined。
  2. 密钥暴露风险:直接在客户端代码中使用Stripe的STRIPE_SECRET_KEY会导致敏感密钥泄露,这是严重的安全问题,绝对禁止这么做。

解决步骤

1. 移除页面的'use client'指令

让首页组件成为服务器组件(App Router中默认就是服务器组件,无需额外声明),这样getStaticProps才能正常执行。

2. 确保Stripe实例仅在服务器端使用

保持./app/utils/stripe.js为服务器组件(不要加'use client'),并指定Stripe API版本避免兼容性问题:

import Stripe from 'stripe';

export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
  apiVersion: '2024-06-20', // 替换为你使用的Stripe API版本
});

3. 修正getStaticProps的返回值

Stripe的products.list()返回的是包含data数组的对象,通常需要传递data而非整个对象给组件:

import { stripe } from "./utils/stripe";

export default function Home({ products }) {
  console.log(products);
  
  return (
    <div>
      home
    </div>
  )
}

export async function getStaticProps() {
  const inventory = await stripe.products.list({
    limit: 5,
  });
  
  return {
    props: {
      products: inventory.data, // 传递data数组
    },
  };
}

4. 若需客户端交互,拆分组件

如果页面需要客户端交互(比如点击事件、状态管理),将客户端逻辑拆分到单独的'use client'组件中,页面主体保持为服务器组件:

  • 创建客户端组件./app/components/ProductList.js:
'use client';

export default function ProductList({ products }) {
  // 这里可以编写客户端交互逻辑
  return (
    <div>
      {products.map(product => (
        <div key={product.id}>{product.name}</div>
      ))}
    </div>
  );
}
  • 修改首页服务器组件:
import { stripe } from "./utils/stripe";
import ProductList from "./components/ProductList";

export default function Home({ products }) {
  console.log(products);
  
  return (
    <div>
      <ProductList products={products} />
    </div>
  )
}

export async function getStaticProps() {
  const inventory = await stripe.products.list({
    limit: 5,
  });
  
  return {
    props: {
      products: inventory.data,
    },
  };
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 14:35:33