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

Next.js集成Stripe Firebase扩展创建结账会话报top-level-await错误

错误原因

你的viewer.js文件在模块顶层(组件函数外)直接使用了await关键字调用getProducts、createCheckoutSession异步方法,顶层await属于ECMAScript实验特性,Next.js默认未开启该特性,因此触发编译报错。

推荐解决方案:将异步逻辑移入组件内部

你当前的异步逻辑都是和页面交互相关的业务逻辑,不应该放在模块顶层执行,更合理的写法是将其放到React的useEffect钩子中,在组件挂载后执行,无需开启实验特性即可正常运行。

修改后的viewer.js参考代码:

import Head from 'next/head'
import Reader from '../components/Reader';
import Header from "../components/Header";
import Feed from "../components/Feed";
import Titles from "../components/Titles"
import React, { useState, useEffect } from 'react';

import { getApp } from "@firebase/app";
import { getStripePayments } from "@stripe/firestore-stripe-payments";
import { getProducts } from "@stripe/firestore-stripe-payments";
import { createCheckoutSession } from "@stripe/firestore-stripe-payments";
import { onCurrentUserSubscriptionUpdate } from "@stripe/firestore-stripe-payments";

const app = getApp();
const payments = getStripePayments(app, {
  productsCollection: "products",
  customersCollection: "customers",
});

// 注意:myPriceId需要你自行定义具体值,原代码中该变量未声明
const myPriceId = "你的价格ID";

function Viewer() {
  useEffect(() => {
    // 所有异步逻辑都放到useEffect内部执行
    const initStripeLogic = async () => {
      const products = await getProducts(payments, {
        includePrices: true,
        activeOnly: true,
      });
      for (const product of products) {
        // ...你的业务逻辑
      }

      const session = await createCheckoutSession(payments, {
        price: myPriceId,
      });
      window.location.assign(session.url);

      onCurrentUserSubscriptionUpdate(
        payments,
        (snapshot) => {
          for (const change in snapshot.changes) {
            if (change.type === "added") {
              console.log(`New subscription added with ID: ${change.subscription.id}`);
            }
          }
        }
      );
    }
    initStripeLogic();
  }, [])

  return (
        <div>
         <Head>
        <title>Minerva</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>
     
        <Header />
          <Reader />  
          
          <div className="pl-28 m-8 text-white">
       <h1 className="text-2xl font-extrabold">Metroid, Chapter 2</h1>
        <p className="font-bold border-b">September 21st, 2021</p>
      </div> 
        
        <Feed />
       
        </div>
    )
}

export default Viewer
可选方案:开启顶层await实验特性

如果你确实需要在模块顶层使用await,可以在Next.js配置中开启对应特性,找到项目根目录的next.config.js文件,添加如下配置:

/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    topLevelAwait: true
  }
}

module.exports = nextConfig

修改配置后重启开发服务即可生效。

注意:你的原代码中myPriceId变量未声明,运行前需要先补充该变量的实际取值,否则会触发变量未定义报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 07:54:06