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

Rails集成Stripe webhook checkout.session.completed报500错误

问题根因

触发500错误的核心原因有两个高概率场景:

  1. Booking.find_by(checkout_session_id: event.data.object.id) 未匹配到对应记录时返回nil,后续直接对nil调用update方法会抛出NoMethodError (undefined method 'update' for nil:NilClass),直接返回500。
  2. 即使匹配到了booking记录,若update操作触发模型层校验失败、前置/后置回调抛出异常,也会导致接口报错。
修复代码

调整checkout.session.completed事件分支的逻辑,增加空值判断、幂等校验和错误日志,修改后完整控制器代码如下:

class WebhooksController < ApplicationController
  skip_before_action :authenticate_user!
  skip_before_action :verify_authenticity_token

  def create
    payload = request.body.read
    sig_header = request.env['HTTP_STRIPE_SIGNATURE']
    event = nil

    begin
      event = Stripe::Webhook.construct_event(
        payload, sig_header, Rails.application.credentials[:stripe][:webhook]
      )
    rescue JSON::ParserError => e
      status 400
      return
    rescue Stripe::SignatureVerificationError => e
      # Invalid signature
      puts "Signature error"
      p e
      return
    end

    # Handle the event
    case event.type
    when 'checkout.session.completed'
      session = event.data.object
      booking = Booking.find_by(checkout_session_id: session.id)

      # 未找到对应预订时打日志返回,不抛出异常
      unless booking
        Rails.logger.error "[Stripe Webhook] 未找到关联预订,checkout_session_id: #{session.id}"
        render json: { message: 'booking not found' }, status: :not_found
        return
      end

      # 幂等处理:已支付的订单直接跳过,避免重复事件触发重复逻辑
      next if booking.paid?

      # 处理更新结果,捕获校验错误
      unless booking.update(paid: true)
        Rails.logger.error "[Stripe Webhook] 预订##{booking.id}支付状态更新失败:#{booking.errors.full_messages.join('; ')}"
        render json: { message: 'update failed', errors: booking.errors.full_messages }, status: :unprocessable_entity
        return
      end
    end

    render json: { message: 'success' }
  end
end
额外排查点
  • 确认创建Stripe Checkout Session的流程中,是否将Stripe返回的session.id正确写入了对应booking记录的checkout_session_id字段,这是最常见的漏操作。
  • 检查Booking模型的回调逻辑(before_save/before_update/after_*系列),确认更新paid字段时不会触发其他依赖缺失的逻辑。
  • 本地调试可使用Stripe CLI将webhook事件转发到本地服务,直接查看控制台抛出的完整错误栈,定位效率远高于查看Stripe后台的状态码日志。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 04:36:14