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/useElementshooks) - 没有在前端调用需要Stripe Secret Key的接口(所有涉及资金操作的API请求必须由后端完成)
内容的提问来源于stack exchange,提问作者vikas deshmukh
相关产品推荐
相关产品推荐

