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

React集成Stripe支付时API密钥认证错误排查求助

React集成Stripe支付网关时的API Key认证错误

错误提示

You did not provide an API key. You need to provide your API key in the Authorization header, using Bearer auth (e.g. 'Authorization: Bearer YOUR_SECRET_KEY'). See https://stripe.com/docs/api#authentication for details, or we can help at https://support.stripe.com/.

App组件代码

// importing modules
import WebFont from "webfontloader";
import { useEffect, useState } from "react";
import Header from "./components/Layout/Header/Header";
import Footer from "./components/Layout/Footer/Footer";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Home from "./components/Home/Home";
import "./App.css";
import { Toaster, toast } from "react-hot-toast";
import ProductDetails from "./components/Product/ProductDetails";
import Products from "./components/Product/Products";
import Search from "./components/Search/Search";
import PageNotFound from "./components/PageNotFound/PageNotFound";
import LoginSignUp from "./components/User/LoginSignUp";
import { useDispatch, useSelector } from "react-redux";
import { loadUser } from "./redux/userSlice";
import UserOptions from "./components/Layout/Header/UserOptions";
import Profile from "./components/User/Profile";
import ProtectedRoute from "./components/Route/ProtectedRoute";
import UpdateProfile from "./components/User/UpdateProfile";
import UpdatePassword from "./components/User/UpdatePassword";
import ForgotPassword from "./components/User/ForgotPassword";
import ResetPassword from "./components/User/ResetPassword";
import Cart from "./components/Cart/Cart";
import Shipping from "./components/Cart/Shipping";
import ConfirmOrder from "./components/Cart/ConfirmOrder"
import Payment from "./components/Cart/Payment"
import axios from "axios";
import { Elements } from "@stripe/react-stripe-js" // compulsory required for using stripe payment gateway
import { loadStripe } from "@stripe/stripe-js" // compulsory required for using stripe payment gateway
import Cookies from 'js-cookie';


function App() {

  // using useDispatch 
  const dispatch = useDispatch();

  const cookieValue = Cookies.get('token');
  console.log(cookieValue)

  // state for stripe api key
  const [stripeApiKey, setStripeApiKey] = useState("");

  // function to receive stripeApiKey
  const getStripeApiKey = async () => {
    try {
      const { data } = await axios.get("/api/v1/stripeapikey", { withCredentials: true });
      if (data.success === false) {
        toast.error("Something went wrong");
      } else {
        setStripeApiKey(data.stripeApiKey);
      }
    } catch (error) {
      toast.error(error.message);
    }
  }

  // using useSelector 
  const { me, isAuthenticated } = useSelector(state => state.user);

  useEffect(() => {
    WebFont.load({
      google: {
        families: ["Roboto", "Droid Sans", "Chilanka"],
      },
    });

    if (cookieValue) {
      // calling function to get user details 
      dispatch(loadUser());
      // calling getStripeApiKey
      getStripeApiKey();
    }

  }, [dispatch, cookieValue]);



  return (
    <BrowserRouter>
      <Header />
      {isAuthenticated && <UserOptions user={me} />}
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/products" element={<Products />} />
        <Route path="/cart" element={<Cart />} />
        <Route path="/search" element={<Search />} />
        <Route path="/shipping" element={<ProtectedRoute><Shipping /></ProtectedRoute>} />
        <Route path="/order/confirm" element={<ProtectedRoute><ConfirmOrder /></ProtectedRoute>} />
        {stripeApiKey && <Route path="/process/payment" element={<ProtectedRoute><Elements stripe={loadStripe(stripeApiKey)}><Payment /></Elements></ProtectedRoute>} />}
        <Route path="/account" element={<ProtectedRoute><Profile /></ProtectedRoute>} />
        <Route path="/me/update" element={<ProtectedRoute><UpdateProfile /></ProtectedRoute>} />
        <Route path="/password/update" element={<ProtectedRoute><UpdatePassword /></ProtectedRoute>} />
        <Route path="/password/forgot" element={<ForgotPassword />} />
        <Route path="/password/reset/:token" element={<ResetPassword />} />
        <Route path="/product/:id" element={<ProductDetails />} />
        <Route path="/products/:keyword" element={<Products />} />
        <Route path="/login" element={<LoginSignUp />} />
        <Route path="*" element={<PageNotFound />} />
      </Routes>
      <Footer />
      <Toaster />
    </BrowserRouter>
  );
}

export default App;

Payment组件代码(注:你提供的内容与App组件代码完全重复,推测为粘贴错误)

// importing modules
import WebFont from "webfontloader";
import { useEffect, useState } from "react";
import Header from "./components/Layout/Header/Header";
import Footer from "./components/Layout/Footer/Footer";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Home from "./components/Home/Home";
import "./App.css";
import { Toaster, toast } from "react-hot-toast";
import ProductDetails from "./components/Product/ProductDetails";
import Products from "./components/Product/Products";
import Search from "./components/Search/Search";
import PageNotFound from "./components/PageNotFound/PageNotFound";
import LoginSignUp from "./components/User/LoginSignUp";
import { useDispatch, useSelector } from "react-redux";
import { loadUser } from "./redux/userSlice";
import UserOptions from "./components/Layout/Header/UserOptions";
import Profile from "./components/User/Profile";
import ProtectedRoute from "./components/Route/ProtectedRoute";
import UpdateProfile from "./components/User/UpdateProfile";
import UpdatePassword from "./components/User/UpdatePassword";
import ForgotPassword from "./components/User/ForgotPassword";
import ResetPassword from "./components/User/ResetPassword";
import Cart from "./components/Cart/Cart";
import Shipping from "./components/Cart/Shipping";
import ConfirmOrder from "./components/Cart/ConfirmOrder"
import Payment from "./components/Cart/Payment"
import axios from "axios";
import { Elements } from "@stripe/react-stripe-js" // compulsory required for using stripe payment gateway
import { loadStripe } from "@stripe/stripe-js" // compulsory required for using stripe payment gateway
import Cookies from 'js-cookie';


function App() {

  // using useDispatch 
  const dispatch = useDispatch();

  const cookieValue = Cookies.get('token');
  console.log(cookieValue)

  // state for stripe api key
  const [stripeApiKey, setStripeApiKey] = useState("");

  // function to receive stripeApiKey
  const getStripeApiKey = async () => {
    try {
      const { data } = await axios.get("/api/v1/stripeapikey", { withCredentials: true });
      if (data.success === false) {
        toast.error("Something went wrong");
      } else {
        setStripeApiKey(data.stripeApiKey);
      }
    } catch (error) {
      toast.error(error.message);
    }
  }

  // using useSelector 
  const { me, isAuthenticated } = useSelector(state => state.user);

  useEffect(() => {
    WebFont.load({
      google: {
        families: ["Roboto", "Droid Sans", "Chilanka"],
      },
    });

    if (cookieValue) {
      // calling function to get user details 
      dispatch(loadUser());
      // calling getStripeApiKey
      getStripeApiKey();
    }

  }, [dispatch, cookieValue]);



  return (
    <BrowserRouter>
      <Header />
      {isAuthenticated && <UserOptions user={me} />}
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/products" element={<Products />} />
        <Route path="/cart" element={<Cart />} />
        <Route path="/search" element={<Search />} />
        <Route path="/shipping" element={<ProtectedRoute><Shipping /></ProtectedRoute>} />
        <Route path="/order/confirm" element={<ProtectedRoute><ConfirmOrder /></ProtectedRoute>} />
        {stripeApiKey && <Route path="/process/payment" element={<ProtectedRoute><Elements stripe={loadStripe(stripeApiKey)}><Payment /></Elements></ProtectedRoute>} />}
        <Route path="/account" element={<ProtectedRoute><Profile /></ProtectedRoute>} />
        <Route path="/me/update" element={<ProtectedRoute><UpdateProfile /></ProtectedRoute>} />
        <Route path="/password/update" element={<ProtectedRoute><UpdatePassword /></ProtectedRoute>} />
        <Route path="/password/forgot" element={<ForgotPassword />} />
        <Route path="/password/reset/:token" element={<ResetPassword />} />
        <Route path="/product/:id" element={<ProductDetails />} />
        <Route path="/products/:keyword" element={<Products />} />
        <Route path="/login" element={<LoginSignUp />} />
        <Route path="*" element={<PageNotFound />} />
      </Routes>
      <Footer />
      <Toaster />
    </BrowserRouter>
  );
}

export default App;

排查原因及解决方法

1. 后端接口返回的API Key有效性问题

  • 确认后端返回的stripeApiKey是Stripe的Publishable Key(格式以pk_开头),绝对不能使用Secret Key(sk_开头,仅用于后端)
  • 在getStripeApiKey函数中添加console.log(data),查看接口返回的完整数据,确认stripeApiKey字段是否存在且不为空

2. 后端接口的认证请求头缺失

当前请求/api/v1/stripeapikey时仅使用了withCredentials: true,但如果后端要求通过Authorization: Bearer <token>头验证身份,需要手动添加请求头:

const getStripeApiKey = async () => {
  try {
    const { data } = await axios.get("/api/v1/stripeapikey", {
      withCredentials: true,
      headers: {
        Authorization: `Bearer ${cookieValue}`
      }
    });
    // ... 后续逻辑
  } catch (error) {
    // ... 错误处理
  }
}

同时检查cookieValue是否正确获取到了用户token,可通过console.log(cookieValue)确认输出内容。

3. Stripe初始化方式优化

loadStripe是异步函数,当前在Route渲染时直接调用可能导致初始化不及时,建议提前缓存Promise:

function App() {
  // ... 其他状态
  const stripePromise = stripeApiKey ? loadStripe(stripeApiKey) : null;

  // ... 其他逻辑

  return (
    // ...
    {stripeApiKey && <Route path="/process/payment" element={<ProtectedRoute><Elements stripe={stripePromise}><Payment /></Elements></ProtectedRoute>} />}
    // ...
  )
}

4. 检查Payment组件的实际代码

由于你提供的Payment组件代码与App组件完全重复,需确认实际Payment组件中:

  • 是否正确使用Stripe提供的组件(如ElementsConsumer或useStripe/useElements hooks)
  • 没有在前端调用需要Stripe Secret Key的接口(所有涉及资金操作的API请求必须由后端完成)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 20:42:35