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

ReactJS中Stripe支付遇Invalid string错误,请求解决

React集成Stripe信用卡扣费报错修复方案

问题背景

我在ReactJS中尝试使用Stripe实现信用卡扣费功能,但出现错误。以下是我的代码、已尝试措施及报错信息:


前端代码

import StripeCheckout from "react-stripe-checkout"
import { useState, useEffect } from "react";
import axios from "axios";
const key="pk_test_51MOn0RSCoZWqhGLghNbZGJNElj6EoHYkt03rWcPYTUpa1EUlMas5Rd2RY8Ta70ubtXaFVmchCdlqOPaXhkpYAQcO00i4y02duY";

export const Pay = () => {
  const [stripeToken, setStripeToken] = useState(null);

  const onToken = (token) => {
    setStripeToken(token);
  };

  useEffect(() => {
    const makeRequest = async () => {
      try {
        const res = await axios.post("http://localhost:8080/api/checkout/payment", {
          tokenId: stripeToken,
          amount: 3000,
        });
        console.log(res.data);
        console.log(res.status);
        console.log(res.data);
      } catch (err) {
        console.log(err);
      }
    };

    if (stripeToken) {
      makeRequest();
    }
  }, [stripeToken]);

  return (
    <>
      <div className="container-fluid">
        <StripeCheckout
          name="shop"
          image="text"
          billingAddress
          shippingAddress
          description="Your total is $2000"
          amount={20000}
          token={onToken}
          stripeKey={key}
        >
          <button className="btn btn-success">Pay</button>
        </StripeCheckout>
      </div>
    </>
  );
}

后端代码

const stripe = require("stripe")(process.env.SECRET_KEY_PAY);

exports.stripePayment = async (req, res, next) => {
  let error, status;
  try {
    const customer = await stripe.customers.create({
      email: req.body.email,
      source: req.body.token,
      payment_method: ['card', 'ach_credit_transfer'],
    });
    const charge = await stripe.paymentIntents.create({
      amount: req.body.amount,
      currency: "inr",
      customer: customer.id,
      description: req.body.description,
    });
    console.log("charge:", { charge });
    status = "success";
  } catch (err) {
    console.log(err);
  }
};

已尝试的解决措施

  • 检查信用卡号和有效期,确认信息正确
  • 使用不同测试信用卡测试
  • 清除浏览器缓存与Cookie

预期结果

成功完成信用卡扣费流程

实际报错信息

StripeInvalidRequestError: Invalid string: {:&quot;0&quot;=&gt;&quot;card&quot;}
    at Function.generate (F:\React\e-commerce site\Api\node_modules\stripe\cjs\Error.js:10:20)
    at res.toJSON.then.Error_js_1.StripeAPIError.message (F:\React\e-commerce site\Api\node_modules\stripe\cjs\RequestSender.js:105:54)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

错误分析与修复方案

核心错误原因

报错指向payment_method参数格式错误:Stripe的customers.create方法中,payment_method要求传入单个支付方法ID字符串,而非数组。同时代码中还存在其他参数不匹配、逻辑冗余问题。

修正后的前端代码

import StripeCheckout from "react-stripe-checkout"
import { useState, useEffect } from "react";
import axios from "axios";
const key="pk_test_51MOn0RSCoZWqhGLghNbZGJNElj6EoHYkt03rWcPYTUpa1EUlMas5Rd2RY8Ta70ubtXaFVmchCdlqOPaXhkpYAQcO00i4y02duY";

export const Pay = () => {
  const [stripeToken, setStripeToken] = useState(null);

  const onToken = (token) => {
    setStripeToken(token);
  };

  useEffect(() => {
    const makeRequest = async () => {
      try {
        const res = await axios.post("http://localhost:8080/api/checkout/payment", {
          tokenId: stripeToken.id, // 传递token的ID而非整个对象
          email: stripeToken.email, // 传递token中携带的邮箱
          amount: 20000, // 与StripeCheckout的amount保持一致(单位为分)
          description: "Your total is $200"
        });
        console.log(res.data);
        alert("支付成功");
      } catch (err) {
        console.error(err);
        alert("支付失败,请重试");
      }
    };

    if (stripeToken) {
      makeRequest();
    }
  }, [stripeToken]);

  return (
    <>
      <div className="container-fluid">
        <StripeCheckout
          name="shop"
          image="https://your-domain.com/payment-icon.png" // 替换为有效图片URL
          billingAddress
          shippingAddress
          description="Your total is $200"
          amount={20000}
          token={onToken}
          stripeKey={key}
        >
          <button className="btn btn-success">Pay</button>
        </StripeCheckout>
      </div>
    </>
  );
}

修正后的后端代码

const stripe = require("stripe")(process.env.SECRET_KEY_PAY);

exports.stripePayment = async (req, res, next) => {
  try {
    // 直接创建Payment Intent(无需提前创建Customer,若需保存客户信息可取消下方注释)
    const paymentIntent = await stripe.paymentIntents.create({
      amount: req.body.amount,
      currency: "inr",
      payment_method_types: ["card"], // 这里用数组指定支持的支付方式类型
      description: req.body.description,
      receipt_email: req.body.email,
    });

    // 如需保存客户信息,可使用以下代码
    // const customer = await stripe.customers.create({
    //   email: req.body.email,
    //   payment_method: req.body.tokenId, // 传入单个支付方法ID
    //   invoice_settings: {
    //     default_payment_method: req.body.tokenId,
    //   },
    // });

    // const paymentIntent = await stripe.paymentIntents.create({
    //   amount: req.body.amount,
    //   currency: "inr",
    //   customer: customer.id,
    //   description: req.body.description,
    // });

    res.status(200).json({
      status: "success",
      clientSecret: paymentIntent.client_secret,
      paymentIntent
    });
  } catch (err) {
    console.error(err);
    res.status(400).json({
      status: "error",
      message: err.message
    });
  }
};

关键修复点

  1. 修正payment_method参数:移除customers.create中的数组格式payment_method,如需指定支付方式类型,在paymentIntents.create中使用payment_method_types数组。
  2. 参数传递匹配:前端传递token的id而非整个对象,后端对应接收并使用;补充传递email和description参数。
  3. 金额统一:保持前端StripeCheckout与后端请求的金额一致(Stripe金额单位为分)。
  4. 添加响应处理:后端返回明确的成功/失败响应,前端根据响应提示用户。
  5. 修复无效参数:替换StripeCheckout中无效的image值为有效图片URL。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 10:12:54