10

Stripe と Ruby on Rails 3.2 を使用して、小さな概念実証を構築しています。これまで、RoR アプリに Stripe を実装する方法について Railscast を見てきましたが、非常にうまく機能しています。

RailsCast #288 Billing with Stripeに従ってアプリを作成しました。これで、私のユーザーは自分のクレジット カードを追加および編集したり、クラスに登録したり、完了時にクレジット カードに請求したりできるようになりました。

現在、Stripe の多数のテスト クレジット カードを使用してテストしており、発生したときにできるだけ多くの例外をキャッチしたいと考えています。ここに示すように、登録モデルでStripe のエラー例を使用しています。

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について読んだことがありますが、考えられるすべての Stripe エラーを処理する最善の方法が何であるかはわかりません。モデルからリダイレクトできないことはわかっていますが、専門家はこれをどのように処理しますか?

ここに私の登録コントローラがあります:

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

お時間を割いてご回答いただき、ありがとうございました。

フランシス

4

1 に答える 1

10

実際の Stripe 呼び出しをカスタム バリデータに入れることを考えたことはありますか?

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

そうすれば、次のようなものでオブジェクトにエラーを追加できます

この背後にあるロジックは、とにかく成功したトランザクションを「トランザクション」として保存したいだけなので、Stripe 料金をバリデーターに入れてみませんか。

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

このようにして、空白のエラー メッセージを表示したり、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
于 2013-04-05T07:59:14.237 に答える