integrallis / stripe_event

Stripe webhook integration for Rails applications.
https://rubygems.org/gems/stripe_event
MIT License
840 stars 107 forks source link

Stripe Dashboard Event Testing #79

Closed j-mcnally closed 7 years ago

j-mcnally commented 7 years ago

I really needed to test a webhook from the UI. So i devised the following to add to an initializer.

if Rails.env.development?
  StripeEvent.event_retriever = lambda do |params|
    Stripe::Event.construct_from(params)
  end
end

This might be worth adding to the documentation, it basically allows us to bypass the fetch retriever in development mode.

invisiblefunnel commented 7 years ago

Can you tell me a bit more about your use case?

benissimo commented 7 years ago

Is this in relation to Stripe Dashboard's "test webhook" button? The README recommends not using that, and it's true that for testing end-to-end integration, you're better off using something like ultrahook and triggering events via the test API.

But it is useful being able to support the "test webhook" button as a quick sanity check for whether a development or staging environment's webhooks are properly configured.

We worked around that with this approach:

  StripeEvent.event_retriever = Integration::Stripe::EventRetriever
module Integration
  module Stripe
    class EventRetriever
      FAKE_EVENT_ID = "evt_00000000000000".freeze

      def self.call(args)
        fetch args[:id], args[:user_id]
      end

      def self.fetch(event_id, stripe_account_id)
        return fetch_fake(event_id) if fake_event?(event_id) && !Rails.env.production?
        # else proceed with looking up event via ::Stripe::Event.retrieve()
        # ...
     end

      def self.fetch_fake(event_id)
        Rails.logger.debug { "Fake stripe event received" }
        ::Stripe::Event.construct_from(
            id: event_id, type: 'account.updated',
            data: { object: "Fake Event" }
        )
      end
      private_class_method :fetch_fake

      def self.fake_event?(event_id)
        FAKE_EVENT_ID == event_id
      end
      private_class_method :fake_event?

ie. we check for whether an incoming event is a "fake event" and, if we're not in production, we generate a dummy in-memory version of the event instead of trying to retrieve it. This is similar to @j-mcnally's approach, except that we only skip retrieving if the event has Stripe's fake event id. That way we can continue to use stripe_event to retrieve other events, even in a development environment.

invisiblefunnel commented 7 years ago

I'm going to close this, but feel free to reopen if you want to discuss further.