Rails5.2でStripeを使う


Rails5.2で色々やってみる という記事で作成したRailsプロジェクトに付け足してStripeによるクレジットカード決済を実装しています。普通に新規プロジェクトを作った続きとして読んで頂いても大体OKなはずです。

まずはGemfileにgemを追加して、bundle installを実行します(gemのバージョンは5.11でした)。

Gemfile
gem 'stripe'

Stripeのダッシュボード Developers -> API Keys にアクセスして「Publishable key」と「Secret Key」を取得しておいてください。

定額の商品を1つ購入するサンプルとして、購入ページ(payment1)と購入完了ページ(payment2)を作成します。

config/routes.rb
  get '/payment1', to: 'pages#payment1'
  post '/payment2', to: 'pages#payment2'

pages_controller.rbが無い場合は以下のコマンドで作成してください。前回の記事でコントローラを作成している場合は不要です。

rails g controller Pages payment1 payment2

コントローラのコードは以下のようになります。payment1はボタン(JavaScript)を置くだけでpayment2では、postされてきたメールアドレスとトークンを元に Customer(顧客) を作成し、さらにそのIDを使って、500円の Charge(決済) を作成します。カードが承認されないなどのエラーが発生した場合は、そのメッセージと共に payment1 にリダイレクトさせています(TODO: メッセージを日本語で取得する方法はあるのかな?)。

app/controllers/pages_controller.rb
  def payment1
  end

  def payment2
    customer = Stripe::Customer.create(
      :email => params[:stripeEmail],
      :source  => params[:stripeToken]
    )

    charge = Stripe::Charge.create(
      :customer    => customer.id,
      :amount      => 500,
      :description => 'From Rails Demo',
      :currency    => 'jpy'
    )
  rescue Stripe::CardError => e
    flash[:error] = e.message
    redirect_to payment1_path
  end

対応するビューの方は以下のような感じ。なるべくシンプルに書いています。先程取得したキーのうち「Publishable」の方をボタンの属性としてセットしています。

app/views/pages/payment1.html.erb
<%= form_tag payment2_path do %>
  <% if flash[:error].present? %>
    <div id="error_explanation">
      <p><%= flash[:error] %></p>
    </div>
  <% end %>
  <p>Total(tax included): ¥500 </p>
  <script src="https://checkout.stripe.com/checkout.js" class="stripe-button"
          data-key="pk_test_DfoKFBIrAGKhxBbDgP0G954e"
          data-description="テスト"
          data-amount="500"
          data-currency="jpy"
          data-locale="auto"></script>
<% end %>
app/views/pages/payment2.html.erb
<p>Thank you for purchasing!</p>
<p><%= link_to 'Back', payment1_path %></p>

「Secret」の方のAPI KeyはRailsのcredentialsの中に保管することにします。以下のコマンドでファイルを開き、

EDITOR=vim rails credentials:edit

最下行に以下のように定義します。

stripe_secret_key: sk_test_xxxxxx

(おまけ)docker-composerを使っている場合は、エディタのインストールが必要です。

docker-compose exec web apt install vim
docker-compose exec -e EDITOR=vim web rails credentials:edit

以下のようにinitializersの中に記述して、credentialsに保存したキーの値をStripeのフレームワークにセットします。

config/initializers/stripe.rb
Stripe.api_key = Rails.application.credentials.stripe_secret_key

以上でローカル環境では動作するようになるはずです。Stripeのダッシュボード Paymentsの一覧に決済が登録されていることを確認してみてください。


(おまけ)Railsのcredentialsを参照するためには、config/master.keyというファイルが必要ですが、Herokuにはアップロードできない(= git addしたくない)ので、代わりにmaster.keyの中に書かれたハッシュ値を環境変数としてセットします。

heroku config:set RAILS_MASTER_KEY=xxxxx

これで、ローカル環境と同様にAPI Keyが読み込まれるようになります。

参考リンク

  • StripeがRailsで動く仕組み
    ほとんどこちらの記事をベースにさせて頂きました。Rails5.2以降の仕様に合わせて鍵の持ち方を変更しています。