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: {:"0"=>"card"} 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 }); } };
关键修复点
- 修正
payment_method参数:移除customers.create中的数组格式payment_method,如需指定支付方式类型,在paymentIntents.create中使用payment_method_types数组。 - 参数传递匹配:前端传递token的
id而非整个对象,后端对应接收并使用;补充传递email和description参数。 - 金额统一:保持前端StripeCheckout与后端请求的金额一致(Stripe金额单位为分)。
- 添加响应处理:后端返回明确的成功/失败响应,前端根据响应提示用户。
- 修复无效参数:替换
StripeCheckout中无效的image值为有效图片URL。
内容的提问来源于stack exchange,提问作者Incogination Khan
相关产品推荐
相关产品推荐

