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

Rails 7生产环境GET请求失效问题排查

排查与解决步骤

1. 修复模板缺失的根本问题

Rails报错找不到模板,本质是控制器动作未通过redirect_to或render明确结束流程。当Easebuzz::Payment.initiate返回的status不等于1,或方法抛出异常时,代码会走到动作末尾,Rails会尝试寻找paye.html.erb模板(你未创建该模板),因此报错。

解决:给动作添加异常捕获和失败分支处理,确保无论成功与否都有明确的跳转:

def paye
  begin
    @payment_response = Easebuzz::Payment.initiate({
      "txnid" => "#{@order.id}_#{SecureRandom.hex(4)}", # 避免重复交易ID
      "amount" => amount.to_f,
      "firstname" => current_user.name,
      "email" => current_user.email,
      "phone" => current_user.phone_number,
      "productinfo" => "Payment for Order#{@order.id}",
      "surl" => "https://#{request.host}/orders/#{@order.id}/successE", # 动态获取域名
      "furl" => "https://#{request.host}/orders/#{@order.id}/failedTransaction",
    })

    Rails.logger.info "Easebuzz payment response: #{@payment_response.inspect}" # 替换puts为Rails日志

    if @payment_response['status'] == 1
      data = @payment_response['data']
      redirect_to("https://pay.easebuzz.in/pay/#{data}", allow_other_host: true, status: 303)
    else
      flash[:error] = "Payment initiation failed: #{@payment_response['message'] || 'Unknown error'}"
      redirect_to @order, status: :unprocessable_entity
    end
  rescue StandardError => e
    Rails.logger.error "Easebuzz payment error: #{e.message}\n#{e.backtrace.join("\n")}"
    flash[:error] = "Failed to start payment. Please try again later."
    redirect_to @order, status: :internal_server_error
  end
end

2. 排查Easebuzz初始化失败的核心原因

2.1 核对生产环境配置

确认config/initializers/easebuzz.rb(或对应配置文件)中的商户ID、API密钥、盐值是生产环境专属参数,而非测试环境配置——配置混淆是生产环境初始化失败的常见原因。

2.2 检查EC2网络权限

AWS EC2安全组需允许出站HTTPS请求到pay.easebuzz.in及Easebuzz的API域名(如api.easebuzz.in);若EC2在VPC内,还需验证网络ACL是否放行对应出站流量。

2.3 避免重复交易ID

支付网关通常禁止重复的txnid,你当前用@order.id作为交易ID,首次支付后再次发起同一订单的支付会被网关拒绝,导致status !=1。解决:给交易ID添加随机后缀(如上述代码中的SecureRandom.hex(4)),确保每次交易ID唯一。

2.4 查看生产日志定位错误

用tail -f log/production.log查看生产日志,日志中会显示@payment_response的具体内容或异常栈,直接定位初始化失败的原因。

3. 优化请求与路由规范

3.1 改用POST请求

支付发起属于写操作,符合REST规范的做法是用POST而非GET:

  • 修改路由:
    resources :orders do
      member do
        post '/paye', to: 'orders#paye'
      end
    end
    
  • 修改视图为POST按钮(避免GET请求被浏览器缓存或爬虫触发):
    <%= button_to "Initiate Payment", paye_order_path(order), method: :post %>
    

3.2 动态生成回调URL

避免硬编码域名,用request.host动态获取当前域名,同时强制使用HTTPS(生产环境建议开启全站HTTPS)。

4. 验证首次可用后续失效场景

首次可用可能是因为订单ID首次使用时网关允许,后续重复使用被拒绝;或生产环境配置存在缓存问题——可重启服务器验证配置是否生效,排查是否有配置加载异常。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 16:35:04