我目前正在为rails应用程序开发stripe-webhook,遇到了一个问题。除checkout.session.completed
外的所有事件都在工作。我的主要目标是在事件checkout.session.completed
发生时将支付状态booking.paid
更改为true
。stripe-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
我只是碰巧正在编写与您完全相同的功能,所以我很高兴这出现在我的队列中。
通过快速查看代码,没有什么特别之处。如果我们知道唯一不起作用的事件是checkout.session.completed
,而且这是我们正在处理的唯一事件,那么问题就缩小了一点。。。我是这么做的:
- 我将您的实现复制到我的Rails API项目中的控制器中,然后使用Stripe CLI来侦听,并将Stripe事件转发到新的端点:
$ stripe listen --forward-to http://localhost:3000/webhook_events
我注释掉了事件的实际处理,所以它只是在处理事件。
然后,我在一个新终端中使用Stripe CLI来触发
checkout.session.completed
事件:
$ stripe trigger checkout.session.completed
- 一旦我这样做了,我的API就回复了
201
,Stripe很高兴
因此,正如前面的答案所表明的,在所有这些之后,我认为问题在于您更新Booking
模型,因此我有一些建议可以让使用Webhook变得更容易:
- 理想情况下,一旦您用Stripe gem验证了事件的真实性,控制器就应该立即向Stripe发出
2xx
响应 - 完成后,我会立即使用ActiveJob将事件处理转移到后台作业
- 在后台作业中,您知道您的事件是有效的,并且会话已成功完成,因此现在可以开始更新
Booking
模型。作业的参数可以简单到只有Stripe签出会话ID - 最后,像这样划分职责将使编写测试变得更加容易(并将发现实际问题是什么!)
我希望这能有所帮助,祝你好运!
我认为问题可能在于Booking.find_by
方法。在更新booking
的状态之前,尝试添加一行来检查其值。
当‘checkout.session.completed’时
在此使用打印(会话)下它将在控制台中显示影响结账会话的错误或显示500错误