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

无法从Stripe获取client_secret以完成支付问题求助

克隆亚马逊页面时Stripe client_secret获取失败排查

问题描述

我跟着视频教程克隆亚马逊页面,在支付流程中遇到无法获取Stripe的client_secret密钥的问题。控制台仅显示初始状态值true,当我将商品添加到购物车并尝试支付时,client_secret既不更新也不生成。

相关代码片段

前端Payment组件代码

import { CardElement, useElements, useStripe } from "@stripe/react-stripe-js";
import React, { useEffect, useState } from "react";
import CurrencyFormat from "react-currency-format";
import CheckoutProducts from "./CheckoutProducts";
import "./Payment.css";
import { getBasketTotal } from "./Reducer";
import { useStateValue } from "./StateProvider";
import axios from "./axios";
import { Link, useNavigate } from "react-router-dom";
import { db } from "./Firebase";

function Payment() {
  const [{ basket, user }, dispatch] = useStateValue();
  const elements = useElements();
  const stripe = useStripe();
  const [error, setError] = useState(null);
  const [disabled, setDisabled] = useState(true);
  const [succeeded, setSucceeded] = useState(false);
  const [processing, setProcessing] = useState("");
  const [clientSecret, setClientSecret] = useState(true);
  const Navigate = useNavigate(); 

  useEffect(()=>{  
    const getClientSecret = async () => {
      const response = await axios({
        method: "post",
        url: `/payments/create?total${getBasketTotal(basket) * 100}`,
      });
      setClientSecret(response.data.clientSecret);
    };
    getClientSecret();
  }, [basket]);
  
  console.log("the secret is>>>", clientSecret);
  console.log(getBasketTotal(basket))
  
  const handleSubmit = async (e) => {
    e.preventDefault();
    setProcessing(true);

    const payload = await stripe
      .confirmCardPayment(clientSecret, {
        payment_method: {
          card: elements.getElement(CardElement),
        },
      })
      .then(({ paymentIntent }) => {
        db.collection("users")
          .doc(user?.uid)
          .collection("Orders")
          .doc(paymentIntent.id)
          .set({
            basket: basket,
            amount: paymentIntent.amount,
            created: paymentIntent.created,
          });

        setSucceeded(true);
        setError(null);
        setProcessing(false);

        dispatch({
          type: "EMPTY__BASKET",
        });
        Navigate("/Orders, { replace: true }");
      });
  };
}

后端云函数代码

const functions = require("firebase-functions");
const express = require("express");
const cors = require("cors");
const stripe = require("stripe")(
  ".... "
);

const app = express();

app.use(cors({origin:true }));
app.use(express.json());

app.get("/", (request, response) => response.status(200).send("hello World"));

app.post("/payments/create", async (request, response) => {
  const total = request.query.total;
  console.log(
    `payment request recieved BOOHOOOO!!! for this amount >>>`,
    total
  );

  const paymentIntent = await stripe.paymentIntents.create({
    amount: total, // subunits of the currency
    currency: "usd",
  });

  response.status(201).send({
    clientSecret: paymentIntent.client_secret,
  });
});

exports.api = functions.https.onRequest(app);

Axios实例配置

import axios from "axios";

const instance=axios.create({
    baseURL:'http://127.0.0.1:5001/cleaver-clone/us-central1/api' // the API (cloud Function) URL
});

export default instance 

排查方向

  • URL参数格式错误:前端请求URL中total参数缺少=号,正确写法应为/payments/create?total=${getBasketTotal(basket) * 100}。参数格式错误会导致后端无法获取total值,进而无法创建Stripe PaymentIntent。
  • 初始状态值不合理:clientSecret初始值设为true,建议改为null或空字符串,避免与返回的密钥字符串混淆,也便于判断是否已获取到有效密钥。
  • 缺少请求错误捕获:前端getClientSecret函数未添加try/catch,无法得知请求是否失败。建议添加错误处理,打印错误信息定位问题:
    const getClientSecret = async () => {
      try {
        const response = await axios({
          method: "post",
          url: `/payments/create?total=${getBasketTotal(basket) * 100}`,
        });
        setClientSecret(response.data.clientSecret);
      } catch (err) {
        console.error("获取clientSecret失败:", err);
      }
    };
    
  • 后端参数校验缺失:后端未校验total参数是否存在或合法,若total为空或非数字,Stripe会抛出错误。建议添加校验逻辑:
    app.post("/payments/create", async (request, response) => {
      const total = request.query.total;
      if (!total || isNaN(total)) {
        return response.status(400).send({ error: "无效的金额参数" });
      }
      // 后续逻辑...
    });
    
  • Stripe密钥验证:确认后端填写的Stripe密钥是有效的测试密钥(以sk_test_开头),而非空值或错误密钥。
  • 云函数运行状态:确认本地云函数模拟器正常运行,访问http://127.0.0.1:5001/cleaver-clone/us-central1/api应返回"hello World",确保API可正常访问。
  • 跳转语法错误:前端Navigate调用存在语法错误,正确写法为Navigate("/Orders", { replace: true });,该错误虽不影响client_secret获取,但会导致支付成功后跳转失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 21:47:15