9

我正在用Stripe和Ruby on Rails 3.2構建一個小概念驗證。到目前爲止,我已經觀看了Railscast如何在RoR應用程序中實現Stripe,並且它工作得很好。在哪裏以及如何處理Stripe異常?

我按照RailsCast #288 Billing with Stripe構建了我的應用程序。現在我的用戶可以添加和編輯他們的信用卡,甚至可以註冊課程,並在完成後開具信用卡。

現在我已經使用Stripe的衆多test credit cards進行了測試,我想在捕捉異常時捕捉很多異常。我使用的是條紋的example錯誤在我註冊模型顯示在這裏:

class Registration < ActiveRecord::Base 

    belongs_to :user 
    belongs_to :session 

    attr_accessible :session_id, :user_id, :session, :user, :stripe_payment_id 
    validates :user_id, :uniqueness => {:scope => :session_id} 

    def save_with_payment(user, stripe_card_token) 
    if valid? 
     if user.stripe_customer_id.present? 
     charge = Stripe::Charge.create(
      :customer => user.stripe_customer_id, 
      :amount => self.session.price.to_i * 100, 
      :description => "Registration for #{self.session.name} (Id:#{self.session.id})", 
      :currency => 'cad' 
     ) 
     else 
     customer = Stripe::Customer.create(
      :email => user.email, 
      :card => stripe_card_token, 
      :description => user.name 
     ) 
     charge = Stripe::Charge.create(
      :customer => customer.id, 
      :amount => self.session.price.to_i * 100, 
      :description => "Registration for #{self.session.name} (Id:#{self.session.id})", 
      :currency => 'cad' 
     ) 
     user.update_attribute(:stripe_customer_id, customer.id) 
     end 
     self.stripe_payment_id = charge.id 
     save! 
    end 
    rescue Stripe::CardError => e 
    body = e.json_body 
    err = body[:error] 
    logger.debug "Status is: #{e.http_status}" 
    logger.debug "Type is: #{err[:type]}" 
    logger.debug "Code is: #{err[:code]}" 
    logger.debug "Param is: #{err[:param]}" 
    logger.debug "Message is: #{err[:message]}" 
    rescue Stripe::InvalidRequestError => e 
    # Invalid parameters were supplied to Stripe's API 
    rescue Stripe::AuthenticationError => e 
    # Authentication with Stripe's API failed 
    # (maybe you changed API keys recently) 
    rescue Stripe::APIConnectionError => e 
    # Network communication with Stripe failed 
    rescue Stripe::StripeError => e 
    # Display a very generic error to the user, and maybe send 
    # yourself an email 
    rescue => e 
    # Something else happened, completely unrelated to Stripe 
    end 
end 

我只是從錯誤中挽救,現在和一個後沒有真正採取行動被提出,並最終我想停止當前類發生註冊並重定向閃爍錯誤的用戶。

我已閱讀約rescure_from,但我不知道什麼是處理所有可能的條紋錯誤的最佳方法。我知道不能從模型中重定向,專家如何處理這個問題?

這裏是我的登記控制器:

class Classroom::RegistrationsController < ApplicationController 
    before_filter :authenticate_user! 

    def new 
    if params[:session_id] 
     @session = Session.find(params[:session_id]) 
     @registration = Registration.new(user: current_user, session: @session) 
    else 
     flash[:error] = "Course session is required" 
    end 

    rescue ActiveRecord::RecordNotFound 
     render file: 'public/404', status: :not_found 

    end 

    def create 
    if params[:session_id] 
     @session = Session.find(params[:session_id]) 
     @registration = Registration.new(user: current_user, session: @session) 
     if @registration.save_with_payment(current_user, params[:stripe_card_token]) 
     flash[:notice] = "Course registration saved with success." 
     logger.debug "Course registration saved with success." 
     mixpanel.track 'Registered to a session', { :distinct_id => current_user.id, 
              :id => @session.id, 
              'Name' => @session.name, 
              'Description' => @session.description, 
              'Course' => @session.course.name 
     } 
     mixpanel.increment current_user.id, { :'Sessions Registered' => 1} 
     mixpanel.track_charge(current_user.id, @session.price.to_i) 
     else 
     flash[:error] = "There was a problem saving the registration." 
     logger.debug "There was a problem saving the registration." 
     end 
     redirect_to root_path 
    else 
     flash[:error] = "Session required." 
     redirect_to root_path 
    end 
    end 

end 

感謝您抽空響應時間,非常感謝!

弗朗西斯

回答

10

你有沒有想過把實際條紋中的呼叫自定義驗證的?

http://apidock.com/rails/ActiveModel/Validations/ClassMethods/validate

這樣,你可以添加錯誤到對象的東西,如以下

這背後的邏輯是,你只需要成功的交易另存爲「交易」反正那麼爲什麼不乾脆把驗證器中的條帶電荷。

validate :card_validation 

def card_validation 

    begin 
     charge = Stripe::Charge.create(
      :customer => user.stripe_customer_id, 
      :amount => self.session.price.to_i * 100, 
      :description => "Registration for #{self.session.name} (Id:#{self.session.id})", 
      :currency => 'cad' 
     ) 
     etc etc 
    rescue => e 
     errors.add(:credit_card, e.message) 
     #Then you might have a model to log the transaction error. 
     Error.create(charge, customer) 
    end 

end 

這樣你就可以像處理任何其他錯誤,你會從一個入口不節能,而不是給一個空白的錯誤信息,或有從條紋處理每一個最後的錯誤提示錯誤。

class Classroom::RegistrationsController < ApplicationController 
    before_filter :authenticate_user! 

    def create 
    if params[:session_id] 
     @session = Session.find(params[:session_id]) 

     params[:registration][:user] = current_user 
     params[:registration][:session] = @session 
     params[:registration][:stripe_card_token] = params[:stripe_card_token] 

     @registration = Registration.new(params[:registration]) 
     respond_with(@registration) do |format| 
     if @registration.save 
      format.html {redirect_to root_path, :notice => "SOMETHING HERE TO TELL THEM SUC"} 
     else 
      format.html {render} 
     end 
     end 
    else 
     respond_with do |format| 
     format.html {redirect_to root_path, :error => "SOMETHING HERE TO TELL THEM GET SESSION"} 
     end 
    end 
    end 

end 
+0

感謝您的意見,我之前從未聽說過custom_validator(剛開始使用rails)。因此,如果我理解正確,我應該將整個Stripe計費邏輯放在我的註冊模型中的一個方法中?那麼註冊控制器會發生什麼?如何重定向閃存錯誤的用戶?對不起,許多問題,仍然困惑:) – 2013-04-05 15:14:01

+1

更新回答它不是100%確切,但一般的想法 – rovermicrover 2013-04-05 15:36:00

+0

我想我得到它,每次註冊模型保存到數據庫,驗證:card_validation將被調用(一點像之前的過濾器),並只保存有效的交易/卡。感謝您的輸入! – 2013-04-05 20:52:20

相關問題