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

Next.js SSR中StripeProvider报错:需传入apiKey或stripe实例

解决Next.js SSR中StripeProvider的报错问题

嘿,我来帮你拆解下你遇到的问题:

首先看你的报错Please pass either 'apiKey' or 'stripe' to StripeProvider,结合你的代码,有两个核心问题:

1. 参数传递错误

你把Stripe实例传给了StripeProvider的apiKey属性,但实际上:

  • apiKey接收的是字符串格式的公钥(比如pk_test_123)
  • 如果要传已初始化的Stripe实例,应该用stripe属性,而不是apiKey

2. Next.js SSR的渲染时机问题

在SSR阶段(服务端渲染时),componentDidMount不会执行,此时你的state.stripe是null,所以初始渲染时StripeProvider拿到的apiKey是null,直接触发了报错。

解决方案一:最简单的方式——直接传递apiKey

让StripeProvider自己处理Stripe实例的初始化,它会自动在客户端完成脚本加载和实例创建,完美适配Next.js SSR:

class Pay extends React.Component {
  render() {
    return (
      {/* 直接传字符串公钥给apiKey */}
      <StripeProvider apiKey="pk_test_123">
        <Elements>
          <InjectedCheckoutForm />
        </Elements>
      </StripeProvider>
    );
  }
}

解决方案二:手动初始化Stripe实例(适合需要自定义初始化逻辑的场景)

如果你一定要自己控制Stripe实例的创建,需要确保只有当实例存在时才渲染StripeProvider,同时正确加载Stripe脚本:

第一步:在_document.js中添加Stripe脚本

确保Stripe脚本在客户端加载:

// pages/_document.js
import Document, { Html, Head, Main, NextScript } from 'next/document';

class MyDocument extends Document {
  render() {
    return (
      <Html>
        <Head>
          <script
            src="https://js.stripe.com/v3/"
            id="stripe-js"
            async
          />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

export default MyDocument;

第二步:修改Pay组件逻辑

等待Stripe实例初始化完成后再渲染StripeProvider:

class Pay extends React.Component {
  constructor() {
    super();
    this.state = { stripe: null };
  }

  componentDidMount() {
    // 处理脚本已加载或未加载的情况
    if (window.Stripe) {
      this.setState({ stripe: window.Stripe('pk_test_123') });
    } else {
      document.querySelector('#stripe-js').addEventListener('load', () => {
        this.setState({ stripe: window.Stripe('pk_test_123') });
      });
    }
  }

  render() {
    const { stripe } = this.state;
    
    // 实例未初始化时,可返回加载状态或null
    if (!stripe) return <div>加载中...</div>;

    // 这里传的是stripe属性,对应已初始化的实例
    return (
      <StripeProvider stripe={stripe}>
        <Elements>
          <InjectedCheckoutForm />
        </Elements>
      </StripeProvider>
    );
  }
}

之前功能正常可能是因为当时的渲染环境没有触发SSR,或者Stripe脚本加载速度足够快,在初始渲染前就完成了实例初始化,但Next.js的SSR会让初始渲染时state为空,所以现在暴露了问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:58:37