Gdzie i jak radzić sobie z wyjątkami Stripe?
Buduję mały proof of concept z Stripe i Ruby on Rails 3.2. Do tej pory oglądałem Railscast o tym, jak zaimplementować Stripe w aplikacji RoR i działa naprawdę dobrze.
Aplikacja została stworzona w oparciu o RailsCast # 288. Teraz moi użytkownicy mogą dodawać i edytować swoje karty kredytowe, a nawet rejestrować się na zajęcia i rozliczać swoje karty kredytowe po zakończeniu.Teraz testowałem z licznymi testowymi kartami kredytowymi i chcę aby złapać jak najwięcej WYJĄTKÓW, gdy podniesione. Używam Stripe ' s przykład błędy w moim modelu Rejestracji, jak pokazano tutaj:
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
Ja tylko ratuję od błędów w tej chwili i nie podejmuję działań po jednym z nich i ostatecznie chciałbym zatrzymać obecną rejestrację klasy i przekierować użytkownika z błędem Flasha.
Czytałem o rescure_from ale nie jestem pewien, jaki jest najlepszy sposób na obsługę wszystkich możliwych błędów Stripe. I wiem, że nie można przekierować z modelu, jak wy eksperci poradzicie sobie z tym?
Oto mój kontroler rejestracji:
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
Dzięki za poświęcenie czasu, aby odpowiedzieć, bardzo doceniam!
Franciszek
1 answers
Czy myślałeś o umieszczeniu połączenia actually Stripe w custom validator?
Http://apidock.com/rails/ActiveModel/Validations/ClassMethods/validate
W ten sposób można dodać błędy do obiektu za pomocą czegoś takiego jak poniżej
Logika stojąca za tym jest taka, że chcesz tylko zapisać udane transakcje jako "transakcja", więc dlaczego nie po prostu umieścić opłatę Stripe w walidatorze.
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
W ten sposób możesz poradzić sobie z błędami jak każdy inne błędy, które można uzyskać z wpisu nie zapisywania, zamiast dać pusty komunikat o błędzie, lub konieczności obsługi każdego ostatniego błędu ze 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) 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-05 15:41:42