<NME> routes.rb
<BEF> Openfoodnetwork::Application.routes.draw do

  root :to => 'home#index'

  # Redirects from old URLs avoid server errors and helps search engines
  get "/enterprises", to: redirect("/")
  get "/products", to: redirect("/")
  get "/products/:id", to: redirect("/")
  get "/about_us", to: redirect(ContentConfig.footer_about_url)

  get "/login", to: redirect("/#/login")
  get '/unauthorized', :to => 'home#unauthorized', :as => :unauthorized

  get "/discourse/login", to: "discourse_sso#login"
  get "/discourse/sso", to: "discourse_sso#sso"

  get "/map", to: "map#index", as: :map
  get "/sell", to: "home#sell", as: :sell

  get "/register", to: "registration#index", as: :registration
  get "/register/auth", to: "registration#authenticate", as: :registration_auth
  post "/user/registered_email", to: "spree/users#registered_email"
  resources :locales, only: [:show]

  # Redirects to global website
  get "/connect", to: redirect("https://openfoodnetwork.org/#{ENV['DEFAULT_COUNTRY_CODE']&.downcase}/connect/")
  get "/learn", to: redirect("https://openfoodnetwork.org/#{ENV['DEFAULT_COUNTRY_CODE']&.downcase}/learn/")

  get "/cart", :to => "spree/orders#edit", :as => :cart
  patch "/cart", :to => "spree/orders#update", :as => :update_cart
  put "/cart/empty", :to => 'spree/orders#empty', :as => :empty_cart
  get '/orders/:id/token/:token' => 'spree/orders#show', :as => :token_order
  get '/payments/:id/authorize' => 'payments#redirect_to_authorize', as: "authorize_payment"

  resource :cart, controller: "cart" do
    post :populate
  end

  resource :shop, controller: "shop" do
    post :order_cycle
    get :order_cycle
    get :changeable_orders_alert
  end

  resources :producers, only: [:index] do
    collection do
      get :signup
    end
  end

  resources :shops, only: [:index] do
    collection do
      get :signup
    end
  end

  resources :line_items, only: [:destroy] do
    get :bought, on: :collection
  end

  resources :groups, only: [:index, :show] do
    collection do
      get :signup
    end
  post 'embedded_shopfront/enable', to: 'application#enable_embedded_styles'
  post 'embedded_shopfront/disable', to: 'application#disable_embedded_styles'

  get '/stripe/callback', :to => 'enterprise#stripe_connect'

  resources :enterprises do
    collection do
  # Temporary re-routing for any pending Stripe payments still using the old return URLs
  constraints ->(request) { request["payment_intent"]&.start_with?("pm_") } do
    match "/checkout", via: :get, controller: "payment_gateways/stripe", action: "confirm"
    match "/orders/:order_number", via: :get, controller: "payment_gateways/stripe", action: "authorize"
  end
  
  namespace :payment_gateways do
    get "/paypal", to: "paypal#express", as: :paypal_express
    get "/paypal/confirm", to: "paypal#confirm", as: :confirm_paypal
    get "/paypal/cancel", to: "paypal#cancel", as: :cancel_paypal

    get "/stripe/confirm", to: "stripe#confirm", as: :confirm_stripe
    get "/stripe/authorize/:order_number", to: "stripe#authorize", as: :authorize_stripe
  end

  constraints FeatureToggleConstraint.new(:split_checkout) do
    get '/checkout', to: 'split_checkout#edit'

    constraints step: /(details|payment|summary)/ do
      get '/checkout/:step', to: 'split_checkout#edit', as: :checkout_step
      put '/checkout/:step', to: 'split_checkout#update', as: :checkout_update
    end
  end

  get '/checkout', to: 'checkout#edit'
  put '/checkout', to: 'checkout#update', as: :update_checkout
  get '/checkout/:state', to: 'checkout#edit', as: :checkout_state

        post :bulk_update, as: :bulk_update
      end

      member do
        get :welcome
        put :register
    end

    member do
      get :shop
      get :relatives
    end
  end
  get '/:id/shop', to: 'enterprises#shop', as: 'enterprise_shop'
  get "/enterprises/:permalink", to: redirect("/") # Legacy enterprise URL

  get 'sitemap.xml', to: 'sitemap#index', defaults: { format: 'xml' }

  unless Rails.env.production?
    # Mount DFC API endpoints
    mount DfcProvider::Engine, at: '/'
  end

  # Mount Spree's routes
  mount Spree::Core::Engine, :at => '/'

  # Errors controller
  match '/404' => 'errors#not_found', via: :all
  match '/500' => 'errors#internal_server_error', via: :all
  match '/422' => 'errors#unprocessable_entity', via: :all
end

<MSG> Stripe auth and callback working. Still need to process callback.

<DFF> @@ -65,7 +65,7 @@ Openfoodnetwork::Application.routes.draw do
   post 'embedded_shopfront/enable', to: 'application#enable_embedded_styles'
   post 'embedded_shopfront/disable', to: 'application#disable_embedded_styles'
 
-  get '/stripe/callback', :to => 'enterprise#stripe_connect'
+  get '/stripe/callback', :to => 'admin/enterprises#stripe_connect_callback'
 
   resources :enterprises do
     collection do
@@ -100,6 +100,8 @@ Openfoodnetwork::Application.routes.draw do
         post :bulk_update, as: :bulk_update
       end
 
+      get "/stripe_connect", to: "enterprises#stripe_connect"
+
       member do
         get :welcome
         put :register

{'commit': 'diff --git a/app/controllers/admin/enterprises_controller.rb b/app/controllers/admin/enterprises_controller.rb\nindex 1e8a4f096..86be4b58f 100644\n--- a/app/controllers/admin/enterprises_controller.rb\n+++ b/app/controllers/admin/enterprises_controller.rb\n@@ -23,6 +23,7 @@ module Admin\n     helper \'spree/products\'\n     include ActionView::Helpers::TextHelper\n     include OrderCyclesHelper\n+    include Admin::StripeHelper\n \n     def index\n       respond_to do |format|\n@@ -113,6 +114,25 @@ module Admin\n       end\n     end\n \n+    def stripe_connect\n+      redirect_to authorize_stripe(params[:enterprise_id]) # csrf: form_authenticity_token)\n+    end\n+\n+    def stripe_connect_callback\n+      if params["code"]\n+        # Get the deets from Stripe\n+\n+        stripe_account = StripeAccount.new(stripe_user_id: params["stripe_user_id"], stripe_publishable_key: params["stripe_publishable_key"], enterprise: enterprise)\n+        if stripe_account.save\n+          render json: stripe_account\n+        else\n+          render text: "Failed to save Stripe token", status: 500\n+        end\n+      else\n+        render text: params["error_description"], status: 500\n+      end\n+    end\n+\n     protected\n \n     def build_resource_with_address\ndiff --git a/app/controllers/enterprises_controller.rb b/app/controllers/enterprises_controller.rb\nindex d913cb4c5..3bbfa6cce 100644\n--- a/app/controllers/enterprises_controller.rb\n+++ b/app/controllers/enterprises_controller.rb\n@@ -11,13 +11,13 @@ class EnterprisesController < BaseController\n \n   before_filter :clean_permalink, only: :check_permalink\n   before_filter :enable_embedded_shopfront\n+  before_filter :set_enterprise, only: :relatives\n \n   respond_to :js, only: :permalink_checker\n \n   def relatives\n     respond_to do |format|\n       format.json do\n-        enterprise = Enterprise.find(params[:id])\n         enterprises = enterprise.andand.relatives.andand.activated\n         render(json: enterprises,\n                each_serializer: Api::EnterpriseSerializer,\n@@ -39,23 +39,13 @@ class EnterprisesController < BaseController\n   end\n \n \n-  def stripe_connect\n-    if params["code"]\n-      # Get the deets from Stripe\n-\n-      stripe_account = StripeAccount.new(stripe_user_id: params["stripe_user_id"], stripe_publishable_key: params["stripe_publishable_key"], enterprise: self) \n-      if stripe_account.save\n-        render_json stripe_account\n-      else\n-        render text "Failed to save Stripe token", status: 500\n-      end\n-    else\n-      render text params["error_description"], status: 500\n-    end\n-  end\n \n   private\n \n+  def set_enterprise\n+    enterprise = Enterprise.find(params[:id])\n+  end\n+\n   def clean_permalink\n     params[:permalink] = params[:permalink].parameterize\n   end\ndiff --git a/app/helpers/admin/stripe_helper.rb b/app/helpers/admin/stripe_helper.rb\nindex 1ec28e7bf..0109b7ba2 100644\n--- a/app/helpers/admin/stripe_helper.rb\n+++ b/app/helpers/admin/stripe_helper.rb\n@@ -1,19 +1,27 @@\n-module StripeHelper\n-  class << self\n-    attr_accessor :client, :options\n-  end\n-  @options = {\n-    :site => \'https://connect.stripe.com\',\n-    :authorize_url => \'/oauth/authorize\',\n-    :token_url => \'/oauth/token\'\n-  }\n-  @client = OAuth2::Client.new(\n-    ENV[\'STRIPE_CLIENT_ID\'],\n-    ENV[\'STRIPE_INSTANCE_SECRET_KEY\'],\n-    options\n-  )\n+module Admin\n+  module StripeHelper\n+    class << self\n+      attr_accessor :client, :options\n+    end\n+    @options = {\n+      :site => \'https://connect.stripe.com\',\n+      :authorize_url => \'/oauth/authorize\',\n+      :token_url => \'/oauth/token\'\n+    }\n+    @client = OAuth2::Client.new(\n+      ENV[\'STRIPE_CLIENT_ID\'],\n+      ENV[\'STRIPE_INSTANCE_SECRET_KEY\'],\n+      options\n+    )\n+\n+    def get_stripe_token(code, options={params: {scope: \'read_write\'}})\n+      StripeHelper.client.get_token(code, options)\n+    end\n \n-  def get_token(code, options={params: {scope: \'read_write\'}})\n-    @client.get_token(code, options)\n+    def authorize_stripe(enterprise_id, options={})\n+      options = options.merge({enterprise_id: enterprise_id})\n+      # State param will be passed back after auth\n+      StripeHelper.client.auth_code.authorize_url(state: options)\n+    end\n   end\n end\ndiff --git a/app/models/enterprise.rb b/app/models/enterprise.rb\nindex 9856c75b9..edf1fe9a7 100644\n--- a/app/models/enterprise.rb\n+++ b/app/models/enterprise.rb\n@@ -42,7 +42,7 @@ class Enterprise < ActiveRecord::Base\n   has_many :billable_periods\n   has_many :inventory_items\n   has_many :tag_rules\n-  has_many :stripe_accounts\n+  has_one :stripe_account, dependent: :destroy\n \n   delegate :latitude, :longitude, :city, :state_name, :to => :address\n \ndiff --git a/app/models/stripe_account.rb b/app/models/stripe_account.rb\nindex b97e8f632..d84f875df 100644\n--- a/app/models/stripe_account.rb\n+++ b/app/models/stripe_account.rb\n@@ -1,5 +1,5 @@\n class StripeAccount < ActiveRecord::Base\n   belongs_to :enterprise\n-  valdates_presence_of :stripe_user_id, :stripe_publishable_key\n-  validates_uniqueness_of :stripe_user_id\n+  validates_presence_of :stripe_user_id, :stripe_publishable_key\n+  validates_uniqueness_of :stripe_user_id, :enterprise_id\n end\ndiff --git a/app/views/admin/enterprises/form/_payment_methods.html.haml b/app/views/admin/enterprises/form/_payment_methods.html.haml\nindex efcde16dc..261fa33bc 100644\n--- a/app/views/admin/enterprises/form/_payment_methods.html.haml\n+++ b/app/views/admin/enterprises/form/_payment_methods.html.haml\n@@ -1,3 +1,5 @@\n+= render \'admin/enterprises/form/stripe_connect\'\n+\n - if @payment_methods.count > 0\n   %table\n     %thead\ndiff --git a/config/routes.rb b/config/routes.rb\nindex 32500d9a1..404214f2f 100644\n--- a/config/routes.rb\n+++ b/config/routes.rb\n@@ -65,7 +65,7 @@ Openfoodnetwork::Application.routes.draw do\n   post \'embedded_shopfront/enable\', to: \'application#enable_embedded_styles\'\n   post \'embedded_shopfront/disable\', to: \'application#disable_embedded_styles\'\n \n-  get \'/stripe/callback\', :to => \'enterprise#stripe_connect\'\n+  get \'/stripe/callback\', :to => \'admin/enterprises#stripe_connect_callback\'\n \n   resources :enterprises do\n     collection do\n@@ -100,6 +100,8 @@ Openfoodnetwork::Application.routes.draw do\n         post :bulk_update, as: :bulk_update\n       end\n \n+      get "/stripe_connect", to: "enterprises#stripe_connect"\n+\n       member do\n         get :welcome\n         put :register\n', 'commit_subject': 'Stripe auth and callback working. Still need to process callback.', 'repo_name': 'openfoodfoundation/openfoodnetwork', 'committer': {'name': 'Rob Harrington', 'email': '4c1b7a69c57001e8088d6662955012658921d8fa@gmail.com', 'time_sec': '1506142622', 'tz_offset': '600', 'date': {'seconds': '1506142622'}}, 'commit_tree': '697d6c68214e806880341b9807f6f4b9892c8e3b', 'commit_message': 'Stripe auth and callback working. Still need to process callback.\n', 'language_name': 'HTML', 'license': 'agpl-3.0', 'hunks': '@@ -65,7 +65,7 @@ Openfoodnetwork::Application.routes.draw do\n   post \'embedded_shopfront/enable\', to: \'application#enable_embedded_styles\'\n   post \'embedded_shopfront/disable\', to: \'application#disable_embedded_styles\'\n \n-  get \'/stripe/callback\', :to => \'enterprise#stripe_connect\'\n+  get \'/stripe/callback\', :to => \'admin/enterprises#stripe_connect_callback\'\n \n   resources :enterprises do\n     collection do\n@@ -100,6 +100,8 @@ Openfoodnetwork::Application.routes.draw do\n         post :bulk_update, as: :bulk_update\n       end\n \n+      get "/stripe_connect", to: "enterprises#stripe_connect"\n+\n       member do\n         get :welcome\n         put :register\n', 'addition_count': 3, 'deletion_count': 1, 'src_file': 'a/config/routes.rb', 'tgt_file': 'b/config/routes.rb', 'file_extension': '.rb', 'before_file': 'Openfoodnetwork::Application.routes.draw do\n\n  root :to => \'home#index\'\n\n  # Redirects from old URLs avoid server errors and helps search engines\n  get "/enterprises", to: redirect("/")\n  get "/products", to: redirect("/")\n  get "/products/:id", to: redirect("/")\n  get "/about_us", to: redirect(ContentConfig.footer_about_url)\n\n  get "/login", to: redirect("/#/login")\n  get \'/unauthorized\', :to => \'home#unauthorized\', :as => :unauthorized\n\n  get "/discourse/login", to: "discourse_sso#login"\n  get "/discourse/sso", to: "discourse_sso#sso"\n\n  get "/map", to: "map#index", as: :map\n  get "/sell", to: "home#sell", as: :sell\n\n  get "/register", to: "registration#index", as: :registration\n  get "/register/auth", to: "registration#authenticate", as: :registration_auth\n  post "/user/registered_email", to: "spree/users#registered_email"\n  resources :locales, only: [:show]\n\n  # Redirects to global website\n  get "/connect", to: redirect("https://openfoodnetwork.org/#{ENV[\'DEFAULT_COUNTRY_CODE\']&.downcase}/connect/")\n  get "/learn", to: redirect("https://openfoodnetwork.org/#{ENV[\'DEFAULT_COUNTRY_CODE\']&.downcase}/learn/")\n\n  get "/cart", :to => "spree/orders#edit", :as => :cart\n  patch "/cart", :to => "spree/orders#update", :as => :update_cart\n  put "/cart/empty", :to => \'spree/orders#empty\', :as => :empty_cart\n  get \'/orders/:id/token/:token\' => \'spree/orders#show\', :as => :token_order\n  get \'/payments/:id/authorize\' => \'payments#redirect_to_authorize\', as: "authorize_payment"\n\n  resource :cart, controller: "cart" do\n    post :populate\n  end\n\n  resource :shop, controller: "shop" do\n    post :order_cycle\n    get :order_cycle\n    get :changeable_orders_alert\n  end\n\n  resources :producers, only: [:index] do\n    collection do\n      get :signup\n    end\n  end\n\n  resources :shops, only: [:index] do\n    collection do\n      get :signup\n    end\n  end\n\n  resources :line_items, only: [:destroy] do\n    get :bought, on: :collection\n  end\n\n  resources :groups, only: [:index, :show] do\n    collection do\n      get :signup\n    end\n  post \'embedded_shopfront/enable\', to: \'application#enable_embedded_styles\'\n  post \'embedded_shopfront/disable\', to: \'application#disable_embedded_styles\'\n\n  get \'/stripe/callback\', :to => \'enterprise#stripe_connect\'\n\n  resources :enterprises do\n    collection do\n  # Temporary re-routing for any pending Stripe payments still using the old return URLs\n  constraints ->(request) { request["payment_intent"]&.start_with?("pm_") } do\n    match "/checkout", via: :get, controller: "payment_gateways/stripe", action: "confirm"\n    match "/orders/:order_number", via: :get, controller: "payment_gateways/stripe", action: "authorize"\n  end\n  \n  namespace :payment_gateways do\n    get "/paypal", to: "paypal#express", as: :paypal_express\n    get "/paypal/confirm", to: "paypal#confirm", as: :confirm_paypal\n    get "/paypal/cancel", to: "paypal#cancel", as: :cancel_paypal\n\n    get "/stripe/confirm", to: "stripe#confirm", as: :confirm_stripe\n    get "/stripe/authorize/:order_number", to: "stripe#authorize", as: :authorize_stripe\n  end\n\n  constraints FeatureToggleConstraint.new(:split_checkout) do\n    get \'/checkout\', to: \'split_checkout#edit\'\n\n    constraints step: /(details|payment|summary)/ do\n      get \'/checkout/:step\', to: \'split_checkout#edit\', as: :checkout_step\n      put \'/checkout/:step\', to: \'split_checkout#update\', as: :checkout_update\n    end\n  end\n\n  get \'/checkout\', to: \'checkout#edit\'\n  put \'/checkout\', to: \'checkout#update\', as: :update_checkout\n  get \'/checkout/:state\', to: \'checkout#edit\', as: :checkout_state\n\n        post :bulk_update, as: :bulk_update\n      end\n\n      member do\n        get :welcome\n        put :register\n    end\n\n    member do\n      get :shop\n      get :relatives\n    end\n  end\n  get \'/:id/shop\', to: \'enterprises#shop\', as: \'enterprise_shop\'\n  get "/enterprises/:permalink", to: redirect("/") # Legacy enterprise URL\n\n  get \'sitemap.xml\', to: \'sitemap#index\', defaults: { format: \'xml\' }\n\n  unless Rails.env.production?\n    # Mount DFC API endpoints\n    mount DfcProvider::Engine, at: \'/\'\n  end\n\n  # Mount Spree\'s routes\n  mount Spree::Core::Engine, :at => \'/\'\n\n  # Errors controller\n  match \'/404\' => \'errors#not_found\', via: :all\n  match \'/500\' => \'errors#internal_server_error\', via: :all\n  match \'/422\' => \'errors#unprocessable_entity\', via: :all\nend\n', 'message': 'Stripe auth and callback working. Still need to process callback.\n', 'author_name': 'Rob Harrington', 'lang': 'rb'}