mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-03-01 02:03:22 +00:00
Add a service object for handling Stripe webhooks
This commit is contained in:
@@ -1,14 +1,11 @@
|
||||
require 'stripe/webhook_handler'
|
||||
|
||||
class StripeController < BaseController
|
||||
def webhook
|
||||
# TODO is there a sensible way to confirm this webhook call is actually from Stripe?
|
||||
event = Stripe::Event.construct_from(params)
|
||||
return render nothing: true, status: 204 unless event.type == "account.application.deauthorized"
|
||||
handler = Stripe::WebhookHandler.new(params)
|
||||
status = handler.handle ? 200 : 204
|
||||
|
||||
destroyed = StripeAccount.where(stripe_user_id: event.account).destroy_all
|
||||
if destroyed.any?
|
||||
render text: "Account #{event.account} deauthorized", status: 200
|
||||
else
|
||||
render nothing: true, status: 204
|
||||
end
|
||||
render nothing: true, status: status
|
||||
end
|
||||
end
|
||||
|
||||
34
lib/stripe/webhook_handler.rb
Normal file
34
lib/stripe/webhook_handler.rb
Normal file
@@ -0,0 +1,34 @@
|
||||
module Stripe
|
||||
class WebhookHandler
|
||||
def initialize(params)
|
||||
@event = Event.construct_from(params)
|
||||
end
|
||||
|
||||
def handle
|
||||
return false unless known_event?
|
||||
send(event_mappings[@event.type])
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def event_mappings
|
||||
{
|
||||
"account.application.deauthorized" => :deauthorize
|
||||
}
|
||||
end
|
||||
|
||||
def known_event?
|
||||
event_mappings.keys.include? @event.type
|
||||
end
|
||||
|
||||
def deauthorize
|
||||
return false unless @event.respond_to?(:account)
|
||||
destroyed = destroy_stripe_accounts_linked_to(@event.account)
|
||||
destroyed.any?
|
||||
end
|
||||
|
||||
def destroy_stripe_accounts_linked_to(account)
|
||||
StripeAccount.where(stripe_user_id: account).destroy_all
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -17,7 +17,6 @@ describe StripeController do
|
||||
it "deletes Stripe accounts in response to a webhook" do
|
||||
post 'webhook', params
|
||||
expect(response.status).to eq 200
|
||||
expect(response.body).to eq "Account webhook_id deauthorized"
|
||||
expect(StripeAccount.all).not_to include stripe_account
|
||||
end
|
||||
|
||||
|
||||
86
spec/lib/stripe/webhook_handler_spec.rb
Normal file
86
spec/lib/stripe/webhook_handler_spec.rb
Normal file
@@ -0,0 +1,86 @@
|
||||
require 'spec_helper'
|
||||
require 'stripe/webhook_handler'
|
||||
|
||||
module Stripe
|
||||
describe WebhookHandler do
|
||||
let(:params) { { type: 'some.event' } }
|
||||
let(:handler) { WebhookHandler.new(params) }
|
||||
|
||||
describe "event_mappings" do
|
||||
it { expect(handler.send(:event_mappings)).to be_a Hash }
|
||||
end
|
||||
|
||||
describe "known_event?" do
|
||||
context "when event mappings know about the event type" do
|
||||
before do
|
||||
allow(handler).to receive(:event_mappings) { { 'some.event' => :something } }
|
||||
end
|
||||
|
||||
it { expect(handler.send(:known_event?)).to be true }
|
||||
end
|
||||
|
||||
context "when event mappings do not know about the event type" do
|
||||
before do
|
||||
allow(handler).to receive(:event_mappings) { { 'some.other.event' => :something } }
|
||||
end
|
||||
|
||||
it { expect(handler.send(:known_event?)).to be false }
|
||||
end
|
||||
end
|
||||
|
||||
describe "handle" do
|
||||
context "when the event is known" do
|
||||
before do
|
||||
allow(handler).to receive(:event_mappings) { { 'some.event' => :some_method } }
|
||||
end
|
||||
|
||||
it "calls the handler method, and returns the result" do
|
||||
expect(handler).to receive(:some_method) { 'result' }
|
||||
expect(handler.handle).to eq 'result'
|
||||
end
|
||||
end
|
||||
|
||||
context "when the event is unknown" do
|
||||
before do
|
||||
allow(handler).to receive(:event_mappings) { { 'some.other.event' => :some_method } }
|
||||
end
|
||||
|
||||
it "does not call the handler method, and returns false" do
|
||||
expect(handler).to_not receive(:some_method)
|
||||
expect(handler.handle).to be false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "deauthorize" do
|
||||
context "when the event has no 'account' attribute" do
|
||||
it "does destroy stripe accounts, returns false" do
|
||||
expect(handler).to_not receive(:destroy_stripe_accounts_linked_to)
|
||||
expect(handler.send(:deauthorize)).to be false
|
||||
end
|
||||
end
|
||||
|
||||
context "when the event has an 'account' attribute" do
|
||||
before do
|
||||
params[:account] = 'some.account'
|
||||
end
|
||||
|
||||
context "when some stripe accounts are destroyed" do
|
||||
before do
|
||||
allow(handler).to receive(:destroy_stripe_accounts_linked_to).with('some.account') { [double(:destroyed_stripe_account)] }
|
||||
end
|
||||
|
||||
it { expect(handler.send(:deauthorize)).to be true }
|
||||
end
|
||||
|
||||
context "when no stripe accounts are destroyed" do
|
||||
before do
|
||||
allow(handler).to receive(:destroy_stripe_accounts_linked_to).with('some.account') { [] }
|
||||
end
|
||||
|
||||
it { expect(handler.send(:deauthorize)).to be false }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user