2016-09-20 45 views
0

我有一个注册页面,用户将输入个人信息以及信用卡信息。 这个信用卡信息与activemerchant集成在一起,并且此信息存储在数据库中。如何更改与活动商家关联的标准表单到Braintree dropin-ui?

这是我的形式:

<%= semantic_form_for(@account, :url => account_create_path, :html => { :multipart => true, :class => 'billing'}) do |f| %> 

    <div class="section section-first"> 
     <%= f.inputs :for => :user do |u| %> 
     <h3>Account Information</h3> 

     <%= u.input :name, :input_html => {:placeholder => "Name", :value => @account.user.name} %> 
     <%= u.input :email, :input_html => {:placeholder => "Email", :value => @account.user.email} %> 
     <% end %> 
    </div> 
     <div class="section"> 
      <%= f.inputs :for => :creditcard do |c| %> 
      <h3>Credit Card Information</h3> 
      <%= c.input :brand, :selected => @creditcard.brand.nil? ? "visa" : @creditcard.brand, :label => "Credit Card", :as => :select, :class => 'dropkick', :include_blank => false, :collection => Saas::Config.gateway == "bogus" ? [['Bogus', 'bogus']] : [['Visa', 'visa'], ['MasterCard', 'master'], ['American Express', 'american_express'], ['Discover', 'discover']] %> 
      <%= c.input :number, :input_html => { :placeholder => "Card Number"}, :label => "Card Number", :as => :numeric %> 

      <li class="select required" id="account_creditcard_expiration_input"> 
       <label for="account_creditcard_expiration">Card Expires On<abbr title="required">*</abbr></label> 
       <%= c.select :year, (Time.now.year .. 10.years.from_now.year), :selected => @creditcard.year.nil? ? Time.now.year : @creditcard.year, :class => 'dropkick dd-small' %> 
       <%= c.select :month, [['1 - January', 1], ['2 - February', 2], ['3 - March', 3], ['4 - April', 4], ['5 - May', 5], ['6 - June', 6], ['7 - July', 7], ['8 - August', 8], ['9 - September', 9], ['10 - October', 10], ['11 - November', 11], ['12 - December', 12]], :selected => @creditcard.month.nil? ? "1" : @creditcard.month, :class => 'dropkick' %> 
      </li> 

      <%= c.input :verification_value, :label => "CVV Code", :input_html => { :placeholder => "CVV Code", :value => @creditcard.verification_value, 
       :type => "password", 
       :class => 'short' } %> 

      <% end %> 

<% end %> 

现在像卡号,有效期等领域;在上述形式必须在braintree投入用户界面(这里本身的信用卡号码由braintree验证)。 如何修改此表单?请帮忙。

这是我的模型,account.rb:

def valid_subscription? 
    return if errors.any? 
    self.build_subscription(:plan => @plan, :next_renewal_at => @plan_start, :creditcard => @creditcard, :address => @address, :affiliate => @affiliate) 
     @address.first_name = @creditcard.first_name 
     @address.last_name = @creditcard.last_name 
    self.subscription.store_card(@creditcard, :billing_address => @address.to_activemerchant) 
    if !subscription.valid? 
     errors.add(:base, "Error with payment: #{subscription.errors.full_messages.to_sentence}") 
     return false 
    end 
    end 

accounts_controller:

class AccountsController < ApplicationController 

    before_filter :build_account, :only => [:new, :create] 
    before_filter :build_user, :only => [:new, :create] 
    before_filter :load_billing, :only => [:new, :create, :billing] 
    def create 
    @address.first_name = @creditcard.first_name 
    @address.last_name = @creditcard.last_name 
    @account.address = @address 
    @account.creditcard = @creditcard 
    if @account.new_record? 
     if @account.save 
     flash[:notice] = 'Account was created.' 
     bypass_sign_in(@user) 
     redirect_to session[:previous_url] || user_reports_path(@user) 
     else 
     render :action => 'new' 
     end 
    else 
     @user.account_id = @account.id 
     if @user.save 
     flash[:notice] = 'User was created.' 
     bypass_sign_in(@user) 
     redirect_to session[:previous_url] || user_reports_path(@user) 
     else 
     render :action => 'new' 
     end 
    end 
    end 

    def billing 
    @user = current_user 
    @account = Account.find(params[:id]) 
    if request.put? 
     @address.first_name = @creditcard.first_name 
     @address.last_name = @creditcard.last_name 
     puts @address.first_name 
     if @creditcard.valid? & @address.valid? 
     if @subscription.store_card(@creditcard, :billing_address => @address.to_activemerchant, :ip => request.remote_ip) 
     flash[:notice] = "Your billing information has been updated." 
     redirect_to settings_path(@user) 
     end 
     end 
    end 
    end 
    protected 

    def resource 
    @account ||= current_account 
    end 

    def build_account 
    @account = params[:account_name].blank? ? Account.new : Account.find_by_name(params[:account_name]) 
    end 

    def build_user 
    @account.user = @user = User.new(params[:account].blank? ? nil : params[:account][:user]) 
    end 

    def load_billing 
    @creditcard = ActiveMerchant::Billing::CreditCard.new(params[:account].blank? ? {} : params[:account][:creditcard]) 
    @address = SubscriptionAddress.new(params[:account].blank? ? {} : params[:account][:address]) 
    end 

end 

这与存款账户模式,subscription.rb相关的另一种模式:

class Subscription < ActiveRecord::Base 

    attr_accessor :creditcard, :address 
    def store_card(creditcard, gw_options = {}) 
    # Clear out payment info if switching to CC from PayPal 
    destroy_gateway_record(paypal) if paypal? 

    @response = if billing_id.blank? 
     gateway.store(creditcard, gw_options) 
    else 
     gateway.update(billing_id, creditcard, gw_options) 
    end 

    if @response.success? 
     if active_card = @response.params['active_card'] 
     # Stripe token-based response 
     self.card_number = "XXXX-XXXX-XXXX-#{active_card['last4']}" 
     self.card_expiration = "%02d-%d" % [active_card['exp_month'], active_card['exp_year']] 
     else 
     self.card_number = creditcard.display_number 
     self.card_expiration = "%02d-%d" % [creditcard.expiry_date.month, creditcard.expiry_date.year] 
     end 
     set_billing 
    else 
     errors.add(:base, @response.message) 
     false 
    end 
    end 

    def card_storage 
     self.store_card(@creditcard, :billing_address => @address.to_activemerchant) if @creditcard && @address && card_number.blank? 
    end 

    def set_billing 
     self.billing_id = @response.token 
    end 

end 

生产.rb:

config.after_initialize do 
    ActiveMerchant::Billing::Base.mode = :production 
    ::GATEWAY = ActiveMerchant::Billing::AuthorizeNetGateway.new(
     :login => "xxxxxxx", 
     :password => "xxxxxxxxxxxxxx" ) 
    end 
+0

您是否尝试添加该插件?他们有一个沙盒和他们的文档:添加插件非常好。到目前为止还没有工作? – eeeeeean

回答

6

声明:我在布伦特里工作。

简答:你不能。 Drop-in意味着作为您主持的信用卡形式的安全替代品。要使用Drop-in,您应该取出表单和帐户模型的整个信用卡部分,而不是预期处理和存储信用卡数据 - 接收由Drop-in返回的payment method nonce,并通过Braintree交易或付款方式API。

长答案:Drop-in是由Braintree托管的预构建表单,我们将通过iframe将其插入到页面的表单中。提交表单时,将来自Drop-in的信用卡(或PayPal等)信息发送给Braintree,并将付款方式随机数返回给您的页面(通过JavaScript回调或插入您的隐藏字段)。随机数是一种随机生成的字符串,代表付款信息,并且可以通过您的应用程序传递而没有安全风险。查看Braintree开发人员文档以获取更多详细信息和示例代码。

所有这些的主要原因是安全性。违反行业法规(称为PCI安全标准)将信用卡信息存储在非安全环境中,并且违反PCI规定永远存储信用卡的CVV /安全代码。 Even having credit card data passing through your site can put it at risk。 Drop-in(或我们托管的字段集成)使符合PCI标准变得更加容易,并减轻了您保护站点的负担。

总结:您应该删除ActiveMerchant中客户信用卡的集成,而不是将它们包含在您的模式中。相反,请在表单中包含一个空白div,以便将插入插入到中,并使用支付方法nonce Drop-in在您的模型/控制器中返回。如何将随机数,服务器端Braintree API调用及其结果集成到您的rails模型中由您决定。我们有一个使用Drop-in的完整示例Rails应用程序:请随时参阅Braintree github页面上的braintree_rails_example回购,以获取创意。

+0

保存我的时间:) –