我正在尝试将StipeConnect连接到我的应用。 我从中下载了简单的代码示例 eav examples 我更新并安装包,复制和更改一些会话文件,但收到错误:
NameError in Users#show
Showing /home/ppl/rps/09.25/app_simple_alpha/app/views/users/_connect.html.erb where line #18 raised:
uninitialized constant ActionView::CompiledTemplates::StripeStandalone
Extracted source (around line #18):
<small>Create a standalone Stripe account in</small>
<select class="country" name="country">
#error line <% StripeStandalone::COUNTRIES.each do |country| %>
<option value="<%= country[:code] %>">
<%= country[:name] %>
</option>
Trace of template inclusion: app/views/users/show.html.erb
这是我的档案:
模型/ user.rb
class User < ActiveRecord::Base
attr_accessor :remember_token, :activation_token, :reset_token
before_save :downcase_email
before_create :create_activation_digest
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
has_secure_password
validates :password, length: { minimum: 6 }, allow_nil: true
serialize :stripe_account_status, JSON
def connected?; !stripe_user_id.nil?; end
def managed?; stripe_account_type == 'managed'; end
def standalone?; stripe_account_type == 'standalone'; end
def oauth?; stripe_account_type == 'oauth'; end
def manager
case stripe_account_type
when 'managed' then StripeManaged.new(self)
when 'standalone' then StripeStandalone.new(self)
when 'oauth' then StripeOauth.new(self)
end
end
def can_accept_charges?
return true if oauth?
return true if managed? && stripe_account_status['charges_enabled']
return true if standalone? && stripe_account_status['charges_enabled']
return false
end
#...
end
控制器/ users_controller.rb
class UsersController < ApplicationController
before_action :logged_in_user, only: [:index, :edit, :update, :destroy]
before_action :correct_user, only: [:edit, :update]
before_action :admin_user, only: :destroy
before_action :require_user, except: %w{ new create }
require 'will_paginate/array'
def index
@users = User.all.paginate(page: params[:page])
end
# ...
def show
@user = User.find(params[:id])
@plans = Stripe::Plan.all
end
def pay
user = User.find( params[:id] )
amount = 1000
fee = (amount * Rails.application.secrets.fee_percentage).to_i
begin
charge_attrs = {
amount: amount,
currency: user.currency,
source: params[:token],
description: "Test Charge via Stripe Connect",
application_fee: fee
}
case params[:charge_on]
when 'connected'
# Use the user-to-be-paid's access token
# to make the charge directly on their account
charge = Stripe::Charge.create( charge_attrs, user.secret_key )
when 'platform'
# Use the platform's access token, and specify the
# connected account's user id as the destination so that
# the charge is transferred to their account.
charge_attrs[:destination] = user.stripe_user_id
charge = Stripe::Charge.create( charge_attrs )
end
flash[:notice] = "Charged successfully! <a target='_blank' rel='#{params[:charge_on]}-account' href='https://dashboard.stripe.com/test/payments/#{charge.id}'>View in dashboard »</a>"
rescue Stripe::CardError => e
error = e.json_body[:error][:message]
flash[:error] = "Charge failed! #{error}"
end
redirect_to user_path( user )
end
def subscribe
user = User.find( params[:id] )
fee_percent = (Rails.application.secrets.fee_percentage * 100).to_i
begin
customer = Stripe::Customer.create(
{
source: params[:token],
email: current_user.email,
plan: params[:plan],
application_fee_percent: fee_percent
},
user.secret_key
)
flash[:notice] = "Subscribed! <a target='_blank' rel='platform-account' href='https://dashboard.stripe.com/test/customers/#{customer.id}'>View in dashboard »</a>"
rescue Stripe::CardError => e
error = e.json_body[:error][:message]
flash[:error] = "Charge failed! #{error}"
end
redirect_to user_path( user )
end
# ...
private
def user_params
params.require(:user).permit(:name, :email, :password,
:password_confirmation, :activation_token)
end
def admin_user
redirect_to(root_url) unless current_user.admin?
end
def logged_in_user
unless logged_in?
store_location
flash[:danger] = "Please log in."
redirect_to login_url
end
end
def correct_user
@user = User.find(params[:id])
redirect_to(root_url) unless current_user?(@user)
end
end
控制器/ stripe_controller.rb
class StripeController < ApplicationController
def managed
connector = StripeManaged.new( current_user )
account = connector.create_account!(
params[:country], params[:tos] == 'on', request.remote_ip
)
if account
flash[:notice] = "Managed Stripe account created! <a target='_blank' rel='platform-account' href='https://dashboard.stripe.com/test/applications/users/#{account.id}'>View in dashboard »</a>"
else
flash[:error] = "Unable to create Stripe account!"
end
redirect_to user_path( current_user )
end
def standalone
connector = StripeStandalone.new( current_user )
account = connector.create_account!( params[:country] )
if account
flash[:notice] = "Standalone Stripe account created! <a target='_blank' rel='platform-account' href='https://dashboard.stripe.com/test/applications/users/#{account.id}'>View in dashboard »</a>"
else
flash[:error] = "Unable to create Stripe account!"
end
redirect_to user_path( current_user )
end
def oauth
connector = StripeOauth.new( current_user )
url, error = connector.oauth_url( redirect_uri: stripe_confirm_url )
if url.nil?
flash[:error] = error
redirect_to user_path( current_user )
else
redirect_to url
end
end
def confirm
connector = StripeOauth.new( current_user )
if params[:code]
# If we got a 'code' parameter. Then the
# connection was completed by the user.
connector.verify!( params[:code] )
elsif params[:error]
# If we have an 'error' parameter, it's because the
# user denied the connection request. Other errors
# are handled at #oauth_url generation time.
flash[:error] = "Authorization request denied."
end
redirect_to user_path( current_user )
end
def deauthorize
connector = StripeOauth.new( current_user )
connector.deauthorize!
flash[:notice] = "Account disconnected from Stripe."
redirect_to user_path( current_user )
end
end
控制器/ hooks_controller.rb
class HooksController < ApplicationController
skip_before_action :verify_authenticity_token
def stripe
user = params[:user_id] && User.find_by( stripe_user_id: params[:user_id] )
args = [ params[:id], user.try(:secret_key) ].compact
begin
event = Stripe::Event.retrieve( *args )
rescue Stripe::InvalidRequestError
render nothing: true, status: 200
return
rescue Stripe::AuthenticationError
if user && user.connected?
connector = StripeConnect.new( user )
connector.deauthorized
end
render nothing: true, status: 200
return
end
case event.try(:type)
when 'account.application.deauthorized'
if user && user.connected?
user.manager.deauthorized
end
when 'account.updated'
if user && user.connected?
user.manager.update_account!
end
when 'charge.succeeded'
Rails.logger.info "**** STRIPE EVENT **** #{event.type} **** #{event.id}"
when 'invoice.payment_succeeded'
Rails.logger.info "**** STRIPE EVENT **** #{event.type} **** #{event.id}"
when 'invoice.payment_failed'
Rails.logger.info "**** STRIPE EVENT **** #{event.type} **** #{event.id}"
end
render nothing: true, status: 200
end
end
控制器/ application_controller.rb
class ApplicationController&lt;的ActionController :: Base的 包括SessionsHelper 包括ApplicationHelper
protect_from_forgery with :: exception
def require_user 如果会话[:user_id] .blank? redirect_to new_sessions_path 返回 结束 结束 端
助手/ application_helper.rb
module ApplicationHelper
def full_title(page_title)
base_title = "GoodApp"
if page_title.empty?
base_title
else
"#{base_title} | #{page_title}"
end
end
# # Lookup logged in user from session, if applicable.
#def current_user
# @_current_user ||= User.find_by_id( session[:user_id] )
#end
def is_myself?
@user == current_user
end
end
资产/ javascrips / application.js中
//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require turbolinks
// require bootstrap-sprockets
//= require app/niceties
//= require app/connect
//= require app/pay
//= require app/subscribe
//= require_tree .
资产/ JavaScript的/应用/ connect.coffee
$(document).ready ->
# pre-connection
setupManaged()
setupStandalone()
# connected user, but we need info
setupFieldsNeeded()
setupManaged = ->
container = $('#stripe-managed')
return if container.length == 0
tosEl = container.find('.tos input')
countrySelect = container.find('.country')
form = container.find('form')
createButton = form.find('.btn')
tosEl.change -> createButton.toggleClass 'disabled', !tosEl.is(':checked')
form.submit ( e ) ->
if !tosEl.is(':checked')
e.preventDefault()
return false
createButton.addClass('disabled').val('...')
countrySelect.change ->
termsUrl = "https://stripe.com/#{countrySelect.val().toLowerCase()}/terms"
tosEl.siblings('a').attr( href: termsUrl )
setupStandalone = ->
container = $('#stripe-standalone')
return if container.length == 0
countrySelect = container.find('.country')
form = container.find('form')
createButton = form.find('.btn')
form.submit ( e ) ->
createButton.addClass('disabled').val('...')
setupFieldsNeeded = ->
container = $('.needed')
return if container.length == 0
form = container.find('form')
form.submit ( e ) ->
button = form.find('.buttons .btn')
button.addClass('disabled').val('Saving...')
if (baContainer = form.find('#bank-account')).length > 0
Stripe.setPublishableKey baContainer.data('publishable')
tokenField = form.find('#bank_account_token')
if tokenField.is(':empty')
e.preventDefault()
Stripe.bankAccount.createToken form, ( _, resp ) ->
if resp.error
button.removeClass('disabled').val('Save Info')
alert( resp.error.message )
else
tokenField.val( resp.id )
form.get(0).submit()
return false
assets/javascript/app/niceties.coffee
$(document).ready ->
setTimeout(
-> $('.alert.alert-info.auto').slideUp('fast')
3500
)
$('body').on 'click', 'a[rel=platform-account]', ( e ) ->
return confirm("This link will only work if you're logged in as the **application owner**. Continue?")
$('body').on 'click', 'a[rel=connected-account]', ( e ) ->
return confirm("This link will only work if you're logged in as the **connected account**. Continue?")
资产/ JavaScript的/应用/ pay.coffee
$(document).ready ->
return unless StripeCheckout?
submitting = false
payButton = $('.pay-button')
form = payButton.closest('form')
destination = form.find('select[name=charge_on]')
indicator = form.find('.indicator').height( form.outerHeight() )
handler = null
createHandler = ->
handler = StripeCheckout.configure
key: window.publishable[destination.val()]
email: window.currentUserEmail
allowRememberMe: false
closed: ->
form.removeClass('processing') unless submitting
token: ( token ) ->
submitting = true
form.find('input[name=token]').val( token.id )
form.get(0).submit()
destination.change createHandler
createHandler()
payButton.click ( e ) ->
e.preventDefault()
form.addClass( 'processing' )
handler.open
name: 'Rails Connect Example'
description: '$10 w/ 10% fees'
amount: 1000
assets/javascript/app/subscribe.coffee
$(document).ready ->
return unless StripeCheckout?
# Holds the plan selected by the user in the interface.
currentPlan = null
submitting = false
subscribeButton = $('.subscribe-button')
planButtons = $('.plan-choice')
form = subscribeButton.closest('form')
indicator = form.find('.indicator').height( form.outerHeight() )
handler = StripeCheckout.configure
key: window.stripePublishableKey
# The email of the logged in user.
email: window.currentUserEmail
allowRememberMe: false
closed: ->
subscribeButton.attr( disabled: true )
planButtons.removeClass('active')
currentPlan = null
form.removeClass('processing') unless submitting
token: ( token ) ->
submitting = true
form.find('input[name=token]').val( token.id )
form.get(0).submit()
planButtons.click ( e ) ->
e.preventDefault()
planButton = $(this)
planButton.addClass('active').siblings().removeClass('active')
subscribeButton.attr( disabled: false )
currentPlan =
id: planButton.data('id')
name: planButton.data('name')
currency: planButton.data('currency')
amount: parseInt planButton.data('amount'), 10
form.find('input[name=plan]').val( currentPlan.id )
subscribeButton.show()
subscribeButton.click ( e ) ->
e.preventDefault()
form.addClass('processing')
if currentPlan == null
alert "Choose a plan first!"
return
handler.open
name: 'Rails Connect Example'
description: "#{currentPlan.name} Subscription"
amount: currentPlan.amount
服务/ stripe_managed.rb
class StripeManaged < Struct.new( :user )
ALLOWED = [ 'US', 'CA' ] # public beta
COUNTRIES = [
{ name: 'United States', code: 'US' },
{ name: 'Canada', code: 'CA' },
{ name: 'Australia', code: 'AU' },
{ name: 'United Kingdom', code: 'GB' },
{ name: 'Ireland', code: 'IE' }
]
def create_account!( country, tos_accepted, ip )
return nil unless tos_accepted
return nil unless country.in?( COUNTRIES.map { |c| c[:code] } )
begin
@account = Stripe::Account.create(
managed: true,
country: country,
email: user.email,
tos_acceptance: {
ip: ip,
date: Time.now.to_i
},
legal_entity: {
type: 'individual',
}
)
rescue
nil # TODO: improve
end
if @account
user.update_attributes(
currency: @account.default_currency,
stripe_account_type: 'managed',
stripe_user_id: @account.id,
secret_key: @account.keys.secret,
publishable_key: @account.keys.publishable,
stripe_account_status: account_status
)
end
@account
end
def update_account!( params: nil )
if params
if params[:bank_account_token]
account.bank_account = params[:bank_account_token]
account.save
end
if params[:legal_entity]
params[:legal_entity][:dob] = {
year: params[:legal_entity].delete('dob(1i)'),
month: params[:legal_entity].delete('dob(2i)'),
day: params[:legal_entity].delete('dob(3i)')
}
params[:legal_entity].entries.each do |key, value|
if [ :address, :dob ].include? key.to_sym
value.entries.each do |akey, avalue|
next if avalue.blank?
account.legal_entity[key] ||= {}
account.legal_entity[key][akey] = avalue
end
else
next if value.blank?
account.legal_entity[key] = value
end
end
pa = account.legal_entity['address'].dup.to_h
account.legal_entity['personal_address'] = pa
account.save
end
end
user.update_attributes(
stripe_account_status: account_status
)
end
def legal_entity
account.legal_entity
end
def needs?( field )
user.stripe_account_status['fields_needed'].grep( Regexp.new( /#{field}/i ) ).any?
end
def supported_bank_account_countries
country_codes = case account.country
when 'US' then %w{ US }
when 'CA' then %w{ US CA }
when 'IE', 'UK' then %w{ IE UK US }
when 'AU' then %w{ AU }
end
COUNTRIES.select do |country|
country[:code].in? country_codes
end
end
protected
def account_status
{
details_submitted: account.details_submitted,
charges_enabled: account.charges_enabled,
transfers_enabled: account.transfers_enabled,
fields_needed: account.verification.fields_needed,
due_by: account.verification.due_by
}
end
def account
@account ||= Stripe::Account.retrieve( user.stripe_user_id )
end
end
服务/ stripe_standalone.rb
class StripeStandalone < Struct.new( :user )
COUNTRIES = [
{ name: 'United States', code: 'US' },
{ name: 'Canada', code: 'CA' },
{ name: 'Australia', code: 'AU' },
{ name: 'United Kingdom', code: 'GB' },
{ name: 'Ireland', code: 'IE' }
]
def create_account!( country )
return nil unless country.in?( COUNTRIES.map { |c| c[:code] } )
begin
@account = Stripe::Account.create(
email: user.email,
managed: false,
country: country
)
rescue
nil # TODO: improve
end
if @account
user.update_attributes(
currency: @account.default_currency,
stripe_account_type: 'standalone',
stripe_user_id: @account.id,
secret_key: @account.keys.secret,
publishable_key: @account.keys.publishable,
stripe_account_status: account_status
)
end
@account
end
protected
def account_status
{
details_submitted: account.details_submitted,
charges_enabled: account.charges_enabled,
transfers_enabled: account.transfers_enabled
}
end
def account
@account ||= Stripe::Account.retrieve( user.stripe_user_id )
end
end
视图/用户/ _connect.html.erb
<div class="panel panel-primary">
<div class="panel-body">
<h3>Connect</h3>
<p>There are 3 ways to create/connect your Stripe account.</p>
<ul class="list-group">
<li class="list-group-item" id="stripe-oauth">
<a class="pull-right btn btn-lg btn-primary" href="<%= stripe_oauth_path %>">Connect</a>
<h3>OAuth</h3>
<p>Connect or create a Stripe account via OAuth.</p>
</li>
<li class="list-group-item" id="stripe-standalone">
<%= form_tag stripe_standalone_path, method: 'POST' do %>
<input class="pull-right btn btn-lg btn-primary" type="submit" value="Create"></input>
<h3>Standalone</h3>
<p>
<small>Create a standalone Stripe account in</small>
<select class="country" name="country">
<% StripeStandalone::COUNTRIES.each do |country| %>
<option value="<%= country[:code] %>">
<%= country[:name] %>
</option>
<% end %>
</select>
</p>
<% end %>
</li>
<% # managed accounts are in public beta %>
<% # see services/stripe_managed.rb#ALLOWED %>
<% if Stripe::Account.retrieve('self').country.in? StripeManaged::ALLOWED %>
<li class="list-group-item" id="stripe-managed">
<%= form_tag stripe_managed_path, method: 'POST' do %>
<input class="pull-right btn btn-lg disabled btn-primary" type="submit" value="Create"></input>
<h3>Managed</h3>
<p>
<small>Create a managed Stripe account in</small>
<select class="country" name="country">
<% StripeManaged::COUNTRIES.each do |country| %>
<option value="<%= country[:code] %>">
<%= country[:name] %>
</option>
<% end %>
</select>
<br/>
<label class="tos">
<input checked="<%= false %>" name="tos" type="checkbox"></input>
I accept the
<a href="https://stripe.com/us/terms" target="_blank">Stripe Terms of Service</a>
</label>
</p>
<% end %>
</li>
<% end %>
</ul>
</div>
视图/用户/ show.html.erb
<div class="col-md-6 col-md-offset-3 col-xs-12">
<%= render partial: 'nav' %>
<% if flash[:notice] %>
<div class="alert alert-info">
<p>
<%= flash[:notice].html_safe %>
</p>
</div>
<% end %>
<% if flash[:error] %>
<div class="alert alert-danger">
<p>
<%= flash[:error].html_safe %>
</p>
</div>
<% end %>
<h1>
<%= @user.name %>
</h1>
<h4>
<%= @user.email %>
</h4>
<% if @user.connected? %>
<% if is_myself? %>
<% # you're looking at your own 'profile', so you can %>
<% # update/deauthorize/etc your Stripe account %>
<%= render partial: 'settings' %>
<% else %>
<%= render partial: 'pay' %>
<% end %>
<% else %>
<% if is_myself? && !current_user.connected? %>
<% # you're looking at your own 'profile', so you can %>
<% # create/connect/etc your Stripe account %>
<%= render partial: 'connect' %>
<% else %>
<div class="panel panel-danger not-connected">
<div class="panel-body">
<h3>Not Connected</h3>
<p>
This user is not connected to Stripe, so
you can't pay them.
</p>
</div>
</div>
<% end %>
<% end %>
</div>
更多详情:https://github.com/rfunduk/rails-stripe-connect-example
感谢您的帮助
答案 0 :(得分:0)
Rails无法加载StripeStandalone
服务。这很奇怪,因为它的名称和路径是正确的,所以Rails应该自动加载它们。但要这样做,您必须在添加新服务后重新启动Rails。
你还说过你正在使用Spring。 Spring允许您通过在第一次运行时预加载Rails并将Rails应用程序保留在后台来更快地加载Rails。因此,如果您使用Spring,则在添加新服务后,您还必须通过运行来重启Spring:
spring stop
再次运行Rails。
这应该对您的情况有所帮助。但如果没有,请将此行添加到config/application.rb
(class Application < Rails::Application
内):
config.autoload_paths << Rails.root.join('app', 'services')
(我希望你不需要这个,因为Rails默认自动加载服务)