tansengming/stripe-rails

No such event error when firing a test webhook event from Stripe Dashboard

heaven opened this issue · 4 comments

My code is very simple, what I'm basically doing is just:

include Stripe::Callbacks

after_stripe_event! do |target, event|
  StripeEvent.create!(event_id: event.id, kind: event.type)
end

From the backtrace it seems like Stripe is trying to load the original event. I'm wondering how I will be testing this. Previously I used to implement my own webhooks controller for stripe and was simply using event id and type. The original even was loaded later on from a sidekiq job. Now it simply slows things down.

2020-05-22T17:21:33.836574+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] Stripe::InvalidRequestError (No such event: evt_00000000000000):
2020-05-22T17:21:33.836575+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03]
2020-05-22T17:21:33.836578+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] stripe (5.22.0) lib/stripe/stripe_client.rb:592:in `handle_error_response'
2020-05-22T17:21:33.836578+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] stripe (5.22.0) lib/stripe/stripe_client.rb:468:in `execute_request_with_rescues'
2020-05-22T17:21:33.836579+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] stripe (5.22.0) lib/stripe/stripe_client.rb:233:in `execute_request'
2020-05-22T17:21:33.836579+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] stripe (5.22.0) lib/stripe/api_operations/request.rb:24:in `request'
2020-05-22T17:21:33.836580+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] stripe (5.22.0) lib/stripe/api_operations/request.rb:76:in `request'
2020-05-22T17:21:33.836580+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] stripe (5.22.0) lib/stripe/api_resource.rb:96:in `refresh'
2020-05-22T17:21:33.836581+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] stripe (5.22.0) lib/stripe/api_resource.rb:103:in `retrieve'
2020-05-22T17:21:33.836581+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] stripe-rails (1.10.0) app/models/stripe/event_dispatch.rb:19:in `retrieve_stripe_event'
2020-05-22T17:21:33.836582+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] stripe-rails (1.10.0) app/models/stripe/event_dispatch.rb:4:in `dispatch_stripe_event'
2020-05-22T17:21:33.836582+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] stripe-rails (1.10.0) app/controllers/stripe/events_controller.rb:7:in `create'
2020-05-22T17:21:33.836583+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action'
2020-05-22T17:21:33.836583+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/abstract_controller/base.rb:195:in `process_action'
2020-05-22T17:21:33.836584+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_controller/metal/rendering.rb:30:in `process_action'
2020-05-22T17:21:33.836585+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/abstract_controller/callbacks.rb:42:in `block in process_action'
2020-05-22T17:21:33.836585+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] activesupport (6.0.3.1) lib/active_support/callbacks.rb:135:in `run_callbacks'
2020-05-22T17:21:33.836586+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/abstract_controller/callbacks.rb:41:in `process_action'
2020-05-22T17:21:33.836586+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_controller/metal/rescue.rb:22:in `process_action'
2020-05-22T17:21:33.836586+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_controller/metal/instrumentation.rb:33:in `block in process_action'
2020-05-22T17:21:33.836587+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] activesupport (6.0.3.1) lib/active_support/notifications.rb:180:in `block in instrument'
2020-05-22T17:21:33.836587+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] activesupport (6.0.3.1) lib/active_support/notifications/instrumenter.rb:24:in `instrument'
2020-05-22T17:21:33.836588+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] activesupport (6.0.3.1) lib/active_support/notifications.rb:180:in `instrument'
2020-05-22T17:21:33.836588+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_controller/metal/instrumentation.rb:32:in `process_action'
2020-05-22T17:21:33.836589+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_controller/metal/params_wrapper.rb:245:in `process_action'
2020-05-22T17:21:33.836589+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] activerecord (6.0.3.1) lib/active_record/railties/controller_runtime.rb:27:in `process_action'
2020-05-22T17:21:33.836590+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/abstract_controller/base.rb:136:in `process'
2020-05-22T17:21:33.836590+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionview (6.0.3.1) lib/action_view/rendering.rb:39:in `process'
2020-05-22T17:21:33.836590+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_controller/metal.rb:190:in `dispatch'
2020-05-22T17:21:33.836591+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_controller/metal.rb:254:in `dispatch'
2020-05-22T17:21:33.836591+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_dispatch/routing/route_set.rb:50:in `dispatch'
2020-05-22T17:21:33.836592+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_dispatch/routing/route_set.rb:33:in `serve'
2020-05-22T17:21:33.836592+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_dispatch/journey/router.rb:49:in `block in serve'
2020-05-22T17:21:33.836593+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_dispatch/journey/router.rb:32:in `each'
2020-05-22T17:21:33.836600+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_dispatch/journey/router.rb:32:in `serve'
2020-05-22T17:21:33.836600+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_dispatch/routing/route_set.rb:834:in `call'
2020-05-22T17:21:33.836601+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] railties (6.0.3.1) lib/rails/engine.rb:527:in `call'
2020-05-22T17:21:33.836601+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] railties (6.0.3.1) lib/rails/railtie.rb:190:in `public_send'
2020-05-22T17:21:33.836602+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] railties (6.0.3.1) lib/rails/railtie.rb:190:in `method_missing'
2020-05-22T17:21:33.836602+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_dispatch/routing/mapper.rb:19:in `block in <class:Constraints>'
2020-05-22T17:21:33.836603+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_dispatch/routing/mapper.rb:48:in `serve'
2020-05-22T17:21:33.836603+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_dispatch/journey/router.rb:49:in `block in serve'
2020-05-22T17:21:33.836604+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_dispatch/journey/router.rb:32:in `each'
2020-05-22T17:21:33.836604+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_dispatch/journey/router.rb:32:in `serve'
2020-05-22T17:21:33.836605+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_dispatch/routing/route_set.rb:834:in `call'
2020-05-22T17:21:33.836605+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] warden (1.2.8) lib/warden/manager.rb:36:in `block in call'
2020-05-22T17:21:33.836606+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] warden (1.2.8) lib/warden/manager.rb:34:in `catch'
2020-05-22T17:21:33.836606+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] warden (1.2.8) lib/warden/manager.rb:34:in `call'
2020-05-22T17:21:33.836606+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] rack (2.2.2) lib/rack/tempfile_reaper.rb:15:in `call'
2020-05-22T17:21:33.836607+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] rack (2.2.2) lib/rack/etag.rb:27:in `call'
2020-05-22T17:21:33.836607+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] rack (2.2.2) lib/rack/conditional_get.rb:40:in `call'
2020-05-22T17:21:33.836608+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] rack (2.2.2) lib/rack/head.rb:12:in `call'
2020-05-22T17:21:33.836608+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_dispatch/http/content_security_policy.rb:18:in `call'
2020-05-22T17:21:33.836609+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] rack (2.2.2) lib/rack/session/abstract/id.rb:266:in `context'
2020-05-22T17:21:33.836609+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] rack (2.2.2) lib/rack/session/abstract/id.rb:260:in `call'
2020-05-22T17:21:33.836609+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_dispatch/middleware/cookies.rb:648:in `call'
2020-05-22T17:21:33.836610+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'
2020-05-22T17:21:33.836610+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] activesupport (6.0.3.1) lib/active_support/callbacks.rb:101:in `run_callbacks'
2020-05-22T17:21:33.836611+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_dispatch/middleware/callbacks.rb:26:in `call'
2020-05-22T17:21:33.836611+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_dispatch/middleware/actionable_exceptions.rb:17:in `call'
2020-05-22T17:21:33.836612+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_dispatch/middleware/debug_exceptions.rb:32:in `call'
2020-05-22T17:21:33.836612+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
2020-05-22T17:21:33.836612+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] railties (6.0.3.1) lib/rails/rack/logger.rb:37:in `call_app'
2020-05-22T17:21:33.836613+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] railties (6.0.3.1) lib/rails/rack/logger.rb:26:in `block in call'
2020-05-22T17:21:33.836613+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] activesupport (6.0.3.1) lib/active_support/tagged_logging.rb:80:in `block in tagged'
2020-05-22T17:21:33.836614+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] activesupport (6.0.3.1) lib/active_support/tagged_logging.rb:28:in `tagged'
2020-05-22T17:21:33.836614+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] activesupport (6.0.3.1) lib/active_support/tagged_logging.rb:80:in `tagged'
2020-05-22T17:21:33.836614+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] railties (6.0.3.1) lib/rails/rack/logger.rb:26:in `call'
2020-05-22T17:21:33.836615+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
2020-05-22T17:21:33.836615+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_dispatch/middleware/request_id.rb:27:in `call'
2020-05-22T17:21:33.836616+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] rack (2.2.2) lib/rack/method_override.rb:24:in `call'
2020-05-22T17:21:33.836621+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] rack (2.2.2) lib/rack/runtime.rb:22:in `call'
2020-05-22T17:21:33.836622+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] activesupport (6.0.3.1) lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call'
2020-05-22T17:21:33.836622+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_dispatch/middleware/executor.rb:14:in `call'
2020-05-22T17:21:33.836623+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_dispatch/middleware/static.rb:126:in `call'
2020-05-22T17:21:33.836623+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] rack (2.2.2) lib/rack/sendfile.rb:110:in `call'
2020-05-22T17:21:33.836624+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_dispatch/middleware/ssl.rb:74:in `call'
2020-05-22T17:21:33.836624+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] actionpack (6.0.3.1) lib/action_dispatch/middleware/host_authorization.rb:76:in `call'
2020-05-22T17:21:33.836625+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] railties (6.0.3.1) lib/rails/engine.rb:527:in `call'
2020-05-22T17:21:33.836625+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] puma (4.3.5) lib/puma/configuration.rb:228:in `call'
2020-05-22T17:21:33.836626+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] puma (4.3.5) lib/puma/server.rb:713:in `handle_request'
2020-05-22T17:21:33.836626+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] puma (4.3.5) lib/puma/server.rb:472:in `process_client'
2020-05-22T17:21:33.836627+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] puma (4.3.5) lib/puma/server.rb:328:in `block in run'
2020-05-22T17:21:33.836627+00:00 app[web.1]: [4fd3254a-7039-4f0c-9661-2b69feffcc03] puma (4.3.5) lib/puma/thread_pool.rb:134:in `block in spawn_thread'

Hi @heaven (wow great handle!), the call to Stripe is protection against spoofing attacks.

if Object.const_defined?('Stripe::Webhook') && sig_header && endpoint_secrets
event = webhook_event(body, sig_header, endpoint_secrets)
else
event = Stripe::Event.retrieve(id)
end

If you're trying to test this with an automated test, I recommend mocking the call to Stripe.

If you're trying to test to see if you have everything hooked up correctly to Stripe, I recommend checking out the "Signing Webhooks" section of the readme: https://github.com/tansengming/stripe-rails#signed-webhooks

Setting up signing skips the call to Stripe since we can verify that the webhook come from Stripe.

Hi @tansengming, thanks ;)

I came up with a bit trickier but working solution.

# code that makes the charge and actually reaches Stripe API
# (we are going to add VCR to reduce the calls but still would like to
# perform the actual calls from time to time).
# charge = do_perform_charge

# Sent charge succeed event
StripeMock.mock do # mocks stripe events
  Sidekiq::Testing.inline! do # processes the event right away
    Stripe::Rails::Testing.send_event "charge.succeeded", charge.to_h
  end
end

So that I use a mocked event from StripeMock but actual charge object.

I've got the idea regarding spoofing protection, that's great and we also do this. Actually, we still do this even with these callbacks. The idea of callbacks is awesome but in our case, we process events asynchronously so this API call is redundant. We only keep event id and type from the callback and store them in the database, in our internal StripeEvent model, which adds itself to Sidekiq queue after commit.

Another idea that came to my mind when I was working with this is that it would be awesome if stripe-rails had it's own Testing module that could be used in tests and would allow to simulate callbacks with actual event returned from Stripe API. I'm not sure if there's API that would allow this but this would be an awesome addition to what we already have.

No worries, I'm glad to hear that you've got it figured out.

I'm not sure it'll work for you but the gem also comes with a testing module https://github.com/tansengming/stripe-rails/#unit-testing

@tansengming Hi, one more addition to this – sending a test event from Stripe Dashboard also fails due to this same problem.

Screen shot 2021-03-15 at 16 27 52