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

ReactJS中Stripe金额变更时如何更新支付请求

解决Stripe PaymentRequest金额不随orderTotal更新的问题

你的代码中,虽然useEffect依赖了orderTotal会重新执行,但旧的PaymentRequest实例监听未清理,且每次重建实例并非最优方案,导致支付按钮仍关联旧金额。以下是具体解决方法:

  • 核心思路:优先复用已有PaymentRequest实例,通过Stripe提供的update方法直接修改金额;同时清理旧事件监听,避免逻辑冲突。

修改后的代码

useEffect(() => {
  let cleanupListener;

  async function syncPaymentRequestAmount() {
    if (!stripe || !elements) return;

    // 已有实例直接更新金额,无需重建
    if (paymentRequest) {
      paymentRequest.update({
        total: {
          label: "Total",
          amount: orderTotal * 100,
        },
      });
      return;
    }

    // 无实例时创建新的PaymentRequest
    const newPaymentRequest = stripe.paymentRequest({
      country: "IND",
      currency: "inr",
      total: {
        label: "Total",
        amount: orderTotal * 100,
      },
      requestPayerName: true,
      // disableWallets: ["link", "browserCard"],
    });

    const canPay = await newPaymentRequest.canMakePayment();
    if (canPay) setPaymentRequest(newPaymentRequest);

    // 绑定支付事件监听并保存引用,用于后续清理
    const handlePaymentMethod = async (event) => {
      const createStripePaymentIntent = await stripeCreatePaymentMethod();
      if (
        createStripePaymentIntent?.success === 1 &&
        createStripePaymentIntent?.gatewayData?.data?.client_secret &&
        createStripePaymentIntent?.gatewayData?.isVerified === false
      ) {
        event.complete("success");
        const confirmpayload = await stripe.confirmCardPayment(
          createStripePaymentIntent?.gatewayData?.data?.client_secret,
          { payment_method: event.paymentMethod.id },
          { handleActions: false }
        );
        if (confirmpayload?.paymentIntent?.status === "succeeded") {
          verifyStripePaymentIntent(confirmpayload?.paymentIntent?.id);
        } else {
          console.log("error");
        }
      } else {
        console.log("error");
        event.complete("fail");
        return;
      }
    };

    newPaymentRequest.on("paymentmethod", handlePaymentMethod);
    cleanupListener = () => {
      newPaymentRequest.off("paymentmethod", handlePaymentMethod);
    };
  }

  syncPaymentRequestAmount();

  // 清理阶段移除旧监听,避免内存泄漏和逻辑冲突
  return () => {
    if (cleanupListener) cleanupListener();
  };

}, [stripe, elements, orderTotal, selectedStore?._id, paymentRequest]);

关键修改说明

  1. 复用实例更新金额:判断已有paymentRequest实例时,直接调用update方法修改total字段,避免重复创建实例的开销。
  2. 清理旧事件监听:保存paymentmethod监听函数的引用,在useEffect的清理回调中调用off移除监听,防止旧实例的逻辑干扰新的支付流程。
  3. 完善依赖数组:添加paymentRequest到依赖项,确保实例变化时能触发正确的更新逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 16:03:09