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

使用Stripe v12.9.0发起支付时触发内部服务器错误求助

Stripe v12.9.0支付请求触发内部服务器错误排查

使用Stripe v12.9.0开发支付功能时,发起支付请求后出现内部服务器错误,以下是相关代码及排查方向:

后端代码

const ErrorHander = require("../utils/errorhander");
const cachasycError = require("../middleware/cachasycError");
const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY);

// 处理支付
exports.paymentProcess = cachasycError(async (req, res, next) => {
  const paymentIntent = await stripe.paymentIntents.create({
    amount: req.body.amount,
    currency: "usd",
    payment_method_types: ["card"],
    metadata: {
      company: "Ecommerce",
    },
  });

  res.status(200).json({
    success: true,
    client_secret: paymentIntent.client_secret,
  });
});

// 返回公钥
exports.publicstripeapikey = cachasycError(async (req, res, next) => {
  res.status(200).json({
    success: true,
    stripeapikey: process.env.STRIPE_API_KEY,
  });
});

前端代码

import React, { Fragment, useEffect, useRef } from "react";
import CheckoutSteps from "../cart/CheckoutSteps";
import { useSelector, useDispatch } from "react-redux";
import MetaData from "../layout/Header/Metadata";
import Typography from "@mui/material/Typography";
import { ToastContainer, toast } from "react-toastify";

import {
  CardNumberElement,
  CardCvcElement,
  CardExpiryElement,
  useStripe,
  useElements,
} from "@stripe/react-stripe-js";

import axios from "axios";
import "./payment.css";
import CreditCardIcon from "@mui/icons-material/CreditCard";
import EventIcon from "@mui/icons-material/Event";
import VpnKeyIcon from "@mui/icons-material/VpnKey";
import { useNavigate } from "react-router-dom";
// import { createOrder, clearErrors } from "../../actions/orderAction";

const Payment = () => {
  const history = useNavigate();

  const orderInfo = JSON.parse(sessionStorage.getItem("orderInfo"));

  // const dispatch = useDispatch();
  const stripe = useStripe();
  const elements = useElements();
  const payBtn = useRef(null);

  const { shippingInfo, cartItems } = useSelector((state) => state.cart);
  const { user } = useSelector((state) => state.user);
  // const { error } = useSelector((state) => state.newOrder);

  const paymentData = {
    amount: Math.round(orderInfo.totalPrice * 100),
  };

  const order = {
    shippingInfo,
    orderItems: cartItems,
    itemsPrice: orderInfo.subtotal,
    taxPrice: orderInfo.tax,
    shippingPrice: orderInfo.shippingCharges,
    totalPrice: orderInfo.totalPrice,
  };

  const submitHandler = async (e) => {
    e.preventDefault();

    payBtn.current.disabled = true;

    try {
      const config = {
        headers: {
          "Content-Type": "application/json",
        },
      };
      const { data } = await axios.post(
        "/api/v1/payment/process",
        paymentData,
        config
      );

      const client_secret = data.client_secret;

      if (!stripe || !elements) return;

      const result = await stripe.confirmCardPayment(client_secret, {
        payment_method: {
          card: elements.getElement(CardNumberElement),
          billing_details: {
            name: user.name,
            email: user.email,
            address: {
              line1: shippingInfo.address,
              city: shippingInfo.city,
              state: shippingInfo.state,
              postal_code: shippingInfo.pinCode,
              country: shippingInfo.country,
            },
          },
        },
      });

      if (result.error) {
        payBtn.current.disabled = false;
        toast(result.error.message);
      } else {
        if (result.paymentIntent.status === "succeeded") {
          order.paymentInfo = {
            id: result.paymentIntent.id,
            status: result.paymentIntent.status,
          };
          console.log("order");
          console.log(order);
          //   dispatch(createOrder(order));

          history("/success");
        } else {
          alert.error("There's some issue while processing payment ");
        }
      }
    } catch (error) {
      payBtn.current.disabled = false;
      // alert.error(error.response.data.message);
    }
  };

  useEffect(() => {
    // if (error) {
    //   alert.error(error);
    //   dispatch(clearErrors());
    // }
  }, [alert]);

  return (
    <Fragment>
      <ToastContainer />
      <MetaData title="Payment" />
      <CheckoutSteps activeStep={2} />
      <div className="paymentContainer">
        <form className="paymentForm" onSubmit={(e) => submitHandler(e)}>
          <Typography>Card Info</Typography>
          <div>
            <CreditCardIcon />
            <CardNumberElement className="paymentInput" />
          </div>
          <div>
            <EventIcon />
            <CardExpiryElement className="paymentInput" />
          </div>
          <div>
            <VpnKeyIcon />
            <CardCvcElement className="paymentInput" />
          </div>

          <input
            type="submit"
            value={`Pay - ₹${orderInfo && orderInfo.totalPrice}`}
            ref={payBtn}
            className="paymentFormBtn"
          />
        </form>
      </div>
    </Fragment>
  );
};

export default Payment;

排查方向

1. 环境变量有效性验证

  • 检查process.env.STRIPE_SECRET_KEY是否正确配置,确保是Stripe提供的测试/生产秘钥,无拼写错误(原文中出现的stipe是笔误,应为stripe)。
  • 在后端代码中添加日志console.log(process.env.STRIPE_SECRET_KEY),确认变量是否成功加载。

2. 支付金额参数校验

  • Stripe要求amount必须是最小货币单位的整数(如USD的分、INR的派萨),前端Math.round(orderInfo.totalPrice * 100)需确保orderInfo.totalPrice是有效数字,计算结果为正整数。
  • 后端需对req.body.amount做校验,避免无效参数传递给Stripe API:
    if (!req.body.amount || typeof req.body.amount !== 'number' || req.body.amount <= 0) {
      return next(new ErrorHander('Invalid payment amount', 400));
    }
    

3. 错误捕获与日志完善

  • 后端的cachasycError应为catchAsyncError(拼写错误),需确认该中间件是否正确捕获异步错误并传递给ErrorHander。
  • 在paymentProcess中添加Stripe API错误捕获,打印详细错误信息:
    exports.paymentProcess = cachasycError(async (req, res, next) => {
      try {
        const paymentIntent = await stripe.paymentIntents.create({
          amount: req.body.amount,
          currency: "usd",
          payment_method_types: ["card"],
          metadata: {
            company: "Ecommerce",
          },
        });
    
        res.status(200).json({
          success: true,
          client_secret: paymentIntent.client_secret,
        });
      } catch (err) {
        console.error('Stripe Error:', err);
        next(new ErrorHander(err.message, err.statusCode || 500));
      }
    });
    

4. 路由与请求配置检查

  • 确认后端/api/v1/payment/process路由已配置为POST方法,且前端请求地址与后端路由一致。
  • 检查跨域配置,但内部服务器错误通常由后端逻辑或Stripe API调用失败导致,跨域问题一般返回4xx状态码。

5. 前端初始化验证

  • 确保前端已通过loadStripe和Elements组件正确初始化Stripe:
    import { loadStripe } from '@stripe/stripe-js';
    import { Elements } from '@stripe/react-stripe-js';
    
    const stripePromise = loadStripe(process.env.REACT_APP_STRIPE_PUBLIC_KEY);
    
    function App() {
      return (
        <Elements stripe={stripePromise}>
          <Payment />
        </Elements>
      );
    }
    

内容的提问来源于stack exchange,提问作者ritik Kumar Sharma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 16:47:02