diff --git a/app/controllers/admin/stripe_accounts_controller.rb b/app/controllers/admin/stripe_accounts_controller.rb new file mode 100644 index 0000000000..bdc7758cbb --- /dev/null +++ b/app/controllers/admin/stripe_accounts_controller.rb @@ -0,0 +1,30 @@ +module Admin + class StripeAccountsController < BaseController + include Admin::StripeHelper + protect_from_forgery except: :destroy_from_webhook + def destroy + if deauthorize_stripe(params[:id]) + respond_to do |format| + format.html { redirect_to main_app.edit_admin_enterprise_path(params[:enterprise_id]), notice: "Stripe account disconnected."} + format.json { render json: stripe_account } + end + else + respond_to do |format| + format.html { redirect_to main_app.edit_admin_enterprise_path(params[:enterprise_id]), notice: "Failed to disconnect Stripe."} + format.json { render json: stripe_account } + end + end + end + + def destroy_from_webhook + event = fetch_event_from_stripe(request) + if event["type"] == "account.application.deauthorized" + StripeAccount.where(stripe_user_id: event["data"]["id"]).map{ |account| account.destroy } + render json: nil, status: 200 + else + render json: nil, status: 501 + end + end + + end +end diff --git a/app/helpers/admin/stripe_helper.rb b/app/helpers/admin/stripe_helper.rb index f7400dd9e3..9b542dff99 100644 --- a/app/helpers/admin/stripe_helper.rb +++ b/app/helpers/admin/stripe_helper.rb @@ -20,6 +20,8 @@ module Admin ENV['STRIPE_INSTANCE_SECRET_KEY'], options ) + # Stripe ruby bindings used for non-Connect functionality + Stripe.api_key = ENV['STRIPE_INSTANCE_SECRET_KEY'] def get_stripe_token(code, options={scope: 'read_write'}) StripeHelper.client.auth_code.get_token(code, options) @@ -41,5 +43,9 @@ module Admin end end + def fetch_event_from_stripe(request) + event_json = JSON.parse(request.body.read) + JSON.parse(Stripe::Event.retrieve(event_json["id"])) + end end end diff --git a/config/routes.rb b/config/routes.rb index a369de8051..0b0627e413 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -66,6 +66,7 @@ Openfoodnetwork::Application.routes.draw do post 'embedded_shopfront/disable', to: 'application#disable_embedded_styles' get '/stripe/callback', :to => 'admin/enterprises#stripe_connect_callback' + get '/stripe/webhook', :to => 'admin/stripe_accounts#destroy_from_webhook' resources :enterprises do collection do diff --git a/spec/controllers/admin/stripe_account_controller_spec.rb b/spec/controllers/admin/stripe_account_controller_spec.rb new file mode 100644 index 0000000000..9f6768eaa4 --- /dev/null +++ b/spec/controllers/admin/stripe_account_controller_spec.rb @@ -0,0 +1,24 @@ +require 'spec_helper' + +describe Admin::StripeAccountsController, type: :controller do + it "deletes Stripe accounts in response to a webhook" do + # https://stripe.com/docs/api#retrieve_event + allow(controller).to receive(:fetch_event_from_stripe) + .and_return({ + "id" => "evt_18zt9YFBE7f7kItLg9f343bn", + "object" => "event", + "created" => 1475350088, + "data" => { + "id" => "webhook_id", + "name" => "OFN", + "object" => "application" + }, + "type" => "account.application.deauthorized" + }) + account = create(:stripe_account, stripe_user_id: "webhook_id") + post 'destroy_from_webhook' + expect(StripeAccount.all).not_to include account + + end + +end diff --git a/spec/helpers/admin/stripe_helper_spec.rb b/spec/helpers/admin/stripe_helper_spec.rb index 12e2feef7e..e80364a788 100644 --- a/spec/helpers/admin/stripe_helper_spec.rb +++ b/spec/helpers/admin/stripe_helper_spec.rb @@ -15,17 +15,17 @@ describe Admin::StripeHelper do context "Disconnecting an account" do it "doesn't destroy the database record if the Stripe API disconnect failed" do - disconnection = Admin::StripeHelper.client + Admin::StripeHelper.client .deauthorize(stripe_account.stripe_user_id) .stub(:deauthorize_request) .and_return(nil) deauthorize_stripe(stripe_account.id) - StripeAccount.last.should eq stripe_account + expect(StripeAccount.all).to include(stripe_account) end it "destroys the record if the Stripe API disconnect succeeds" do - disconnection = Admin::StripeHelper.client + Admin::StripeHelper.client .deauthorize(stripe_account.stripe_user_id) .stub(:deauthorize_request) .and_return("something truthy") @@ -33,5 +33,6 @@ describe Admin::StripeHelper do deauthorize_stripe(stripe_account.id) expect(StripeAccount.all).not_to include(stripe_account) end + end end