【问题标题】:500 error for stripe webhook event checkout.session.completed条带 webhook 事件 checkout.session.completed 的 500 错误
【发布时间】:2022-10-18 16:49:53
【问题描述】:

我目前正在为我的 rails 应用程序开发条带 webhook,但遇到了问题。除了checkout.session.completed 之外的所有事件都在工作。 我的主要目标是在事件checkout.session.completed 发生时将付款状态booking.paid 更改为true。条带 webhook 日志为事件 checkout.session.completed 提供了 500 个内部服务器错误。我认为问题出在我的 Webhook 控制器上,但我就是不知道出了什么问题。任何帮助都会很棒!

这是我的 Webhooks_controller:

 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.session.client_reference_id.paid = true
      booking = Booking.find_by(checkout_session_id: event.data.object.id)
      booking.update(paid: true)
    end

    render json: { message: 'success' }
  end
end

【问题讨论】:

  • 如果出现服务器错误,则应将错误消息和堆栈跟踪写入您的日志文件或报告给您的错误跟踪系统。请分享完整的错误消息和堆栈跟踪。
  • @spickermann 是的,我现在收到此错误:签名错误#<Stripe::SignatureVerificationError: No signatures found matching the expected signature for payload> No template found for WebhooksController#create, rendering head:no_content Completed 204 No Content in 0ms (Allocations:第594章)
  • 你最终进入了这个rescue Stripe::SignatureVerificationError 块。可能是因为您没有正确设置凭据。该块最后只是简单地调用return。但是,相反,您需要呈现一些 JSON 错误响应。这意味着:首先修复设置并确保您在应用程序中配置了正确的凭据和机密。其次,确保即使出现错误也能返回有用的 JSON 响应。

标签: ruby-on-rails ruby stripe-payments payment


【解决方案1】:

我只是碰巧正在编写与您完全相同的功能,所以我很高兴这突然出现在我的队列中。

从快速浏览代码来看,没有什么特别突出的。如果我们知道唯一不起作用的事件是checkout.session.completed,而这是我们正在处理的唯一事件,那么问题就会缩小一点……所以这就是我所做的:

  1. 我将您的实现复制到我的 Rails API 项目中的控制器中,然后使用 Stripe CLI 监听并将 Stripe 事件转发到新端点:
    $ stripe listen --forward-to http://localhost:3000/webhook_events
    
    1. 我注释掉了事件的实际处理,所以它只处理事件。

    2. 然后我在新终端中使用 Stripe CLI 来触发 checkout.session.completed 事件:

    $ stripe trigger checkout.session.completed
    
    1. 一旦我这样做了,我的 API 就回复了 201,Stripe 很高兴。

    所以毕竟,正如前面的答案所暗示的那样,我认为问题在于您更新 Booking 模型,所以我有一些建议可以让使用 webhook 更容易:

    1. 理想情况下,一旦您使用 Stripe gem 验证了事件的真实性,您的控制器应该立即向 Stripe 回复 2xx
    2. 一旦完成,我会立即使用 ActiveJob 将事件处理转移到后台作业。
    3. 在后台作业中,您知道您的事件有效并且会话成功完成,因此现在您可以开始更新您的Booking 模型。作业的参数可以像 Stripe 结帐会话 ID 一样简单。
    4. 最后,像这样划分职责将使编写测试变得更加容易(并且会发现实际问题是什么!)。

      我希望这会有所帮助,祝你好运!

【讨论】:

  • 非常感谢您的详细回答,我真的很感激!我现在正在使用他的条纹 cli。我为每个事件获得 204 回报。但是在控制台中我收到一个错误:签名错误#<Stripe::SignatureVerificationError: No signatures found matching the expected signature for payload> No template found for WebhooksController#create, rendering head :no_content Completed 204 No Content in 0ms (Allocations: 594 ) 你可能知道那是什么意思吗?
  • 验证错误有点红鲱鱼,我也遇到过。幸运的是,模板错误很容易修复——当您最终在控制器中呈现响应时,您将需要一个像 JBuilder 视图这样的模板视图,或者您可以简单地使用像 render json: { state: "processed" }, status: :ok 这样的东西。
  • the render json: { state: "processed" }, status: :ok 线在我的控制器中应该放在哪里?
  • 它应该是控制器中操作的最后一行
【解决方案2】:

我认为问题可能在于Booking.find_by 方法。在更新其状态之前,尝试添加一行以检查 booking 的值。

【讨论】:

    【解决方案3】:

    当'checkout.session.completed'

    在此使用 print(session) 它将在控制台中显示影响或在结帐会话中显示 500 错误的错误

    【讨论】:

      猜你喜欢
      • 2013-12-02
      • 2017-02-09
      • 2020-01-10
      • 2021-07-21
      • 2017-01-13
      • 2019-05-18
      • 2016-03-09
      • 2021-04-03
      • 2022-01-13
      相关资源
      最近更新 更多