You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Ruby传递动态金额创建Stripe Payment Intent时触发500错误的问题求助

Ruby传递动态金额创建Stripe Payment Intent时触发500错误的问题求助

你好,我仔细看了你的代码,发现几个关键问题导致了500错误,咱们一步步梳理解决:

1. Ruby后端获取请求参数的核心错误

你的/create-payment-intent路由里直接用了data['total'],但在Sinatra中,你没有先解析POST请求的JSON请求体data变量根本未定义,这会直接抛出异常,触发500错误。

修改你的Ruby路由代码:

post '/create-payment-intent' do
  # 先解析请求体的JSON数据
  request.body.rewind
  data = JSON.parse(request.body.read)
  
  # 重要提醒:Stripe的amount要求是最小货币单位(比如美元是分)
  # 若前端传的是美元金额(如10.99),需乘以100转成分
  total_cents = (data['total'].to_f * 100).to_i
  
  payment_intent = Stripe::PaymentIntent.create({
    amount: total_cents,
    currency: 'usd',
    automatic_payment_methods: { enabled: true }
  })

  { clientSecret: payment_intent.client_secret }.to_json
end

这里必须注意Stripe的amount参数规则:必须传入最小货币单位的整数,如果直接传前端的浮点数金额,Stripe会返回参数错误,这也是常见的踩坑点。

2. 前端代码的请求冲突问题

你在payment.js里已经通过POST请求的JSON体传递了total,但在HTML底部的script中,又把form的action改成了/create-payment-intent?total=${total},这会导致:

  • 请求方式冲突(后端路由是POST,而form默认提交是GET)
  • 重复传递参数引发逻辑混乱

建议直接删除HTML底部的这段代码:

// Update the form action URL to include the total as a query parameter
const form = document.getElementById('payment-form');
form.action = `/create-payment-intent?total=${total}`;

因为你已经在payment.js里通过AJAX请求创建了Payment Intent,不需要再通过form的action传递参数。

3. 额外调试建议

  • 查看Sinatra日志:你已经配置了logger,可以去C:\s\starter-ruby\server\logs/development.log里看详细报错信息,这能帮你快速定位问题
  • 前端增加错误捕获:在fetch("/create-payment-intent")请求里添加错误处理,方便在控制台查看后端返回的具体错误:
const response = await fetch("/create-payment-intent", {
  method: "POST",
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ total: total })
});

if (!response.ok) {
  const errorData = await response.json();
  console.error("后端错误详情:", errorData);
  throw new Error("创建支付意图失败");
}

const { clientSecret } = await response.json();

按照上面的修改,应该能解决你的500错误问题,建议先优先处理后端参数解析和金额单位转换的核心问题。

备注:内容来源于stack exchange,提问作者Danijel Krnic

火山引擎 最新活动