PAYATHON 2026

如何将 Rails 中 NET::HTTP post_form 超时设为 60 秒

支付老李

结论

Net::HTTP.post_form(uri, payment_details) 不支持直接传入超时参数。要把超时时间设为 60 秒,需要创建 Net::HTTP 实例,设置 open_timeout 和 read_timeout,再发送表单请求。

示例代码

uri = URI.parse(payment_api_url)

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = (uri.scheme == "https")

http.open_timeout = 60
http.read_timeout = 60

request = Net::HTTP::Post.new(uri.request_uri)
request.set_form_data(payment_details)

begin
  response = http.request(request)

  logger.info "HTTP STATUS: #{response.code}"
  logger.info "RESPONSE: #{response.body}"

  if response.is_a?(Net::HTTPSuccess)
    decrypted_response = JSON.parse(response.body)
    logger.info "PARSED RESPONSE: #{decrypted_response}"
  else
    logger.error "Payment API returned HTTP #{response.code}: #{response.body}"
  end
rescue Net::OpenTimeout => e
  logger.error "Payment API connection timed out: #{e.message}"
rescue Net::ReadTimeout => e
  logger.error "Payment API response timed out: #{e.message}"
rescue JSON::ParserError => e
  logger.error "Payment API returned invalid JSON: #{e.message}"
rescue StandardError => e
  logger.error "Payment API request failed: #{e.class}: #{e.message}"
end

如果当前 Ruby 版本支持 write_timeout,也可以加上:

http.write_timeout = 60

各超时参数的含义

  • open_timeout:建立 TCP 连接及 HTTPS 连接过程允许等待的时间。
  • read_timeout:连接建立后,读取服务器响应允许等待的时间。
  • write_timeout:向服务器写入请求数据允许等待的时间,能否使用取决于 Ruby 版本。

这些参数分别限制连接、读取和写入阶段,并不表示整个请求最多执行 60 秒。如果必须严格限制整个操作的总时长,还需要在应用层设置总截止时间。

为什么原来的写法无法设置

Net::HTTP.post_form 是一个便捷类方法,适用于不需要调整连接参数的简单请求。它没有提供设置 open_timeout、read_timeout 等选项的入口,所以需要改用 Net::HTTP.new。

表单内容仍通过以下方法发送:

request.set_form_data(payment_details)

它与 post_form 一样,可用于发送 application/x-www-form-urlencoded 表单。

支付请求需要特别注意

读取超时并不表示支付服务器一定没有处理请求。有时支付已经成功,只是响应在返回途中超时。此时直接重试,可能造成重复扣款。

建议这样处理:

  • 每次请求都携带唯一且稳定的业务订单号或幂等键。
  • 超时后,先调用支付平台的订单查询接口确认状态。
  • 确认原请求未成功后,再重新发起支付。
  • 分别记录 HTTP 状态码、异常类型、订单号和响应正文,但不要记录银行卡号、密钥、签名原文等敏感数据。
  • 不要只根据 response.body 判断请求是否成功,还要检查 HTTP 状态码和支付接口返回的业务状态。

把超时时间增加到 60 秒,只是延长了等待时间,无法解决第三方服务不稳定、网络中断,或请求已经受理但响应丢失等问题。对于支付接口,幂等处理和支付状态核验通常比延长超时时间更重要。

备注:内容仅供参考。