ruby on rails - Where and how to handle Stripe exceptions? -
i'm building small proof of concept stripe , ruby on rails 3.2. far i've watched railscast on how implement stripe in ror app , it's working well.
i've built app following railscast #288 billing stripe. users can add , edit credit cards , register classes , have credit card billed upon completion.
now i've been testing stripe's numerous test credit cards , want catch many exceptions when raised. i'm using stripe's example errors in registration model show here:
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 #{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 #{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 supplied stripe's api rescue stripe::authenticationerror => e # authentication stripe's api failed # (maybe changed api keys recently) rescue stripe::apiconnectionerror => e # network communication stripe failed rescue stripe::stripeerror => e # display generic error user, , maybe send # email rescue => e # else happened, unrelated stripe end end
i'm merely rescuing errors right , not taking action after 1 being raised , stop current class registration happening , redirect user flash error.
i've read rescure_from i'm not sure best way handle of possible stripe errors. know can't redirect model, how experts handle this?
here's registration controller:
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 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 success." logger.debug "course registration saved success." mixpanel.track 'registered 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 problem saving registration." logger.debug "there problem saving registration." end redirect_to root_path else flash[:error] = "session required." redirect_to root_path end end end
thanks taking time respond, appreciated!
francis
have thought of putting stripe call in custom validator?
http://apidock.com/rails/activemodel/validations/classmethods/validate
that way add errors object following
the logic behind want save successful transactions 'transaction' anyway why not put stripe charge in validator.
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 #{self.session.name} (id:#{self.session.id})", :currency => 'cad' ) etc etc rescue => e errors.add(:credit_card, e.message) #then might have model log transaction error. error.create(charge, customer) end end
this way can handle errors other errors entry not saving, instead of giving blank error message, or having handle every last error stripe.
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) |format| if @registration.save format.html {redirect_to root_path, :notice => "something here tell them suc"} else format.html {render} end end else respond_with |format| format.html {redirect_to root_path, :error => "something here tell them session"} end end end end
Comments
Post a Comment