MERN项目集成Stripe支付网关遇API密钥认证错误求助
Stripe支付网关集成MERN项目时的认证错误排查
错误信息
StripeAuthenticationError: 未提供API密钥。需要在Authorization头部使用Bearer认证方式提供API密钥(例如:'Authorization: Bearer YOUR_SECRET_KEY')。
错误堆栈片段:
D:\Visual Studio Code\Projects\MERN Projects\Online Movie Ticket Booking System\server\node_modules\stripe\cjs\RequestSender.js:96 err = new Error_js_1.StripeAuthenticationError(jsonResponse.error); ^
问题场景
将Stripe支付网关集成到MERN项目中,调用Stripe API时触发上述认证错误。已检查代码和环境变量,确认密钥设置逻辑,且在App.jsx中能成功获取并打印stripeApikey,但错误依然存在。以下是相关代码片段:
后端PaymentController代码
const express = require("express"); const router = express.Router(); const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY); router.post("/process", async (req, res, next) => { const myPayment = await stripe.paymentIntents.create({ amount: req.body.amount, currency: "inr", metadata: { company: "Mahadi", }, }); console.log("Stripe Secret Key:", process.env.STRIPE_SECRET_KEY); res.status(200).json({ success: true, client_secret: myPayment.client_secret, }); }); router.get("/stripeapikey", async (req, res, next) => { console.log("Stripe API Key:", process.env.STRIPE_API_KEY); res.status(200).json({ stripeApikey: process.env.STRIPE_API_KEY }); }); module.exports = router;
前端App.jsx代码
const [stripeApikey, setStripeApiKey] = useState(""); async function getStripeApikey() { try { const { data } = await axios.get(`${server}/payment/stripeapikey`); setStripeApiKey(data.stripeApikey); console.log("Stripe API Key:", data.stripeApikey); } catch (error) { console.error("Error fetching Stripe API key:", error); } } console.log(stripeApikey); useEffect(() => { getStripeApikey(); }, []); return ( <> <BrowserRouter> {stripeApikey && ( <Elements stripe={loadStripe(stripeApikey)}> <Routes> <Route path="/booking" element={ <ProtectedRoute> <BookingPage /> </ProtectedRoute> } /> </Routes> </Elements> )}
前端BookingPage.jsx核心支付逻辑
const handleSubmit = async (e) => { e.preventDefault(); try { const config = { headers: { "Content-Type": "application/json", }, }; const paymentData = { amount: ticketPrice * 100, // Stripe要求金额以分为单位 }; const { data } = await axios.post( `${server}/payment/process`, paymentData, config ); const client_secret = data.client_secret; if (!stripe || !elements) { toast.error("Stripe或Elements未初始化。"); return; } const result = await stripe.confirmCardPayment(client_secret, { payment_method: { card: elements.getElement(CardNumberElement), }, }); if (result.error) { toast.error(result.error.message); } else { if (result.paymentIntent.status === "succeeded") { const reservationData = { movieName, theaterName, showDate, selectedShowtime, selectedHall, selectedSeats, ticketPrice, paymentInfo: { id: result.paymentIntent.id, status: result.paymentIntent.status, type: "Credit Card", }, }; dispatch(createReservation(reservationData)); toast.success("预订成功!"); navigate("/ticket", { state: { movieName, theaterName, showDate, selectedShowtime, selectedHall, selectedSeats, ticketPrice, }, }); } else { toast.error("支付处理失败,请重试。"); } } } catch (error) { toast.error(error.message); } };
Stripe卡片组件代码
<div className="w-[50%] mb-5"> <label className="block pb-3 text-[black]"> 有效期 <span className="text-red-500">*</span>{" "} </label> <CardExpiryElement className="w-full border p-1 rounded-[5px]" options={{ style: { base: { fontSize: "15px", lineHeight: 1.5, color: "#444", }, empty: { color: "#3a120a", backgroundColor: "transparent", "::placeholder": { color: "#444", }, }, }, }} /> </div> </div> <div className="w-full pb-3 "> <div className="w-[50%] mb-5"> <label className="block pb-3 text-[black]"> 卡号 <span className="text-red-500">*</span>{" "} </label> <CardNumberElement className={`w-full border p-1 rounded-[5px] !h-[35px]`} options={{ style: { base: { fontSize: "15px", lineHeight: 1.5, color: "#444", }, empty: { color: "#3a120a", backgroundColor: "transparent", "::placeholder": { color: "#444", }, }, }, }} /> </div> <div className="w-[50%] "> <label className="block pb-3 text-[black]"> CVV <span className="text-red-500">*</span>{" "} </label> <CardCvcElement className="w-full border p-1 rounded-[5px] !h-[35px]" options={{ style: { base: { fontSize: "15px", lineHeight: 1.5, color: "#444", }, empty: { color: "#3a120a", backgroundColor: "transparent", "::placeholder": { color: "#444", }, }, }, }} /> </div> </div>
排查及解决方案
确认后端环境变量加载状态
- 检查后端
.env文件,确保STRIPE_SECRET_KEY拼写正确,值为Stripe后台获取的Secret Key(格式为sk_test_xxxxxx或sk_live_xxxxxx),而非Publishable Key。 - 修改
.env后必须重启后端服务,process.env仅在服务启动时加载新值。 - 在初始化Stripe实例前打印
process.env.STRIPE_SECRET_KEY,确认输出为完整有效密钥,而非undefined或空字符串。
- 检查后端
规范Stripe实例初始化顺序
- 确保
dotenv配置在引入Stripe之前执行:require('dotenv').config(); // 置于代码最顶部 const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY);
- 确保
验证密钥类型正确性
- 前端使用Publishable Key(
pk_test_xxxxxx),后端使用Secret Key,二者不可混用。检查/stripeapikey接口返回的是否为正确的Publishable Key。
- 前端使用Publishable Key(
排查网络请求拦截问题
- 确认后端服务器可正常访问Stripe服务,无防火墙或代理拦截请求导致Authorization头部丢失。
内容的提问来源于stack exchange,提问作者user21744021
相关产品推荐
相关产品推荐

