Railsでのstripe(クレジット決済)の使い方

##はじめに
※この記事はstripeにもうすでに登録している体で書いていきます。

railsへの導入については公式サイトに記載されています。
https://stripe.com/docs/checkout/rails
ですが、ちょこちょこ自分なりに修正したのでそれを書いていきます。

ログイン機能はdeviseで実装する前提で書いてますので、`current_user`はユーザー情報が格納されています。`current_user.email`はユーザーのemailアドレスを指しています。

##導入
`Gemfile`に`gem "stripe"`を追加し`bundle install`

##コントローラー作成

```sh
$ rails g controller charges
```

##ルート指定
公式では`resources :charges`で指定していますが、ぼくはこのように追加しました。

```routes.rb
post "products/:id/charge", to: "charges#create", as: "charge"
```

今回はcreate処理のみ実装していきます。

`products`というのは商品を扱うパスになります。

↓のように商品個別ページに決済ボタンを配置するような実装方法をとっています。

<img width="656" alt="スクリーンショット 2019-06-01 21.51.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399745/c9ac2938-01a3-5d65-ce10-def6d4f52f33.png">

ですので`"products/:id/charge"`の`:id`は商品のidが入ります。

##購入ボタン実装

```show.html.erb
<%= form_tag charge_path(@product) do %>
  <script src="https://checkout.stripe.com/checkout.js" class="stripe-button"
    data-key="<%= Rails.configuration.stripe[:publishable_key] %>"
    data-amount="<%= @product.price %>"
    data-currency="jpy"
    data-description="クレジット決済"
    data-name=<%= "#{@product.name}を購入" %>
    data-email=<%= "#{current_user.email}" %>
    data-label="購入する"
    data-image="https://stripe.com/img/documentation/checkout/marketplace.png"
    data-locale="auto"
    data-allow-remember-me="false">
  </script>
<% end %>
```

slimで書くとこのようになりますね。

```show.html.slim
= form_tag charge_path(@product) do
  script.stripe-button data-amount="#{@product.price}\
  " data-currency="jpy" data-description="クレジット決済\
  " data-key="#{Rails.configuration.stripe[:publishable_key]}" data-locale="auto" data-name="#{@product.name}を購入\
  " data-email="#{current_user.email}" data-label="購入する\
  " data-allow-remember-me="false" src="https://checkout.stripe.com/checkout.js"
```

`@product`には商品名や金額などの商品データが入ってます。

使用しているcheckout.jsのオプションについて説明していきます。

商品購入ボタンを押下したとき次のようなモーダルが表示されます。

<img width="330" alt="スクリーンショット_2019-06-01_22_14_59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399745/1a785f01-650e-0373-95ff-dc2e7567b513.png">

`data-key`は公式サンプルコードのままでよいです。**必須項目**です。

###①アイコン
`data-image`はべつになくても。。。飾りです。

###②名称
`data-name`はこの決済の名称です。

###③説明文
`data-description`は↑の説明文です。

###④ユーザーのメールアドレス
`data-email`はユーザーのメールアドレスを指定してあげることにより、emailアドレスを入力する手間を省いています。
`current_user`はログイン機能をdeviseで実装しているのでそのユーザー情報が格納されています。
公式のサンプルコードでは`data-email`を指定していない為、メールアドレス入力欄が表示されます。

**ここで注意点があります。**
`data-email`を指定する場合は、ユーザー登録時に必ず`sample@example.com`のような形で登録させるようにしてください。例えば`aaa@aaa`だとstripe側の保存処理でエラーになってしまいます。
ログイン機能にdeviseを使っている場合はメール認証を実装していれば問題ないと思うのですが、デフォルトの状態では`aaa@aaa`でも登録できるので注意です。
`data-email`を指定せず、メールアドレス入力欄から入力する仕様の場合はメールアドレスが正しい形でないときは再入力する形になるので問題ないです。

###⑤支払いボタン
`data-amount`は金額を指定します。ボタンに反映されます。
`data-currency`で`jpy`を指定しているので日本円表示になっています。
`data-locale`で`auto`を指定しているので「を支払う」と自動的に日本語にしてくれています。
うまくいかない場合は`"jp"`を指定してあげてください。

###⑥決済情報を保存

`data-allow-remember-me`は決済情報を保存するかどうかのチェックボックスが表示されます。
今回はfalseにしていますが、true及び指定していない場合はこちらが表示されます。

<img width="240" alt="スクリーンショット_2019-06-01_23_03_56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399745/b665adff-5445-49c4-6ae5-899b9d2687e4.png">

決済情報を保存するときはコントローラ側で保存処理が必要だと思うのですが、今回はやっていません。ですが、実装してたらなんとなくわかると思うので試してみてください！

###⑦商品ページの購入ボタンのラベル
`data-label`は商品ページの購入ボタンのラベルです。

<img width="193" alt="スクリーンショット 2019-06-01 22.34.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399745/86a205b8-2078-73fa-ad16-165d11ed5e8d.png">

###オプションまとめ

他にもいろいろとオプションがあるのでまとめてみました。

|  オプション名  |    内容    | 実装例 |
|-----------|---------------|------------|
| data-image | フォームの上部に表示されるアイコン | data-image=URL |
| data-name | ショップ名や商品名などの名称 | data-name="定期便" |
| data-description | `data-name`に対する説明文 | data-description="説明文" |
| data-amount | 課金額 | data-amount="250" |
| data-locale | 言語を設定 <br> 未設定の場合"en"(英語) | data-locale="ja" |
| data-currency | 通貨設定 <br> 未設定の場合"USD" | data-currency="JPY" |
| data-panel-label | モーダルの支払いボタンのラベル | data-panel-label="250円を支払う" |
| data-label | 親画面の購入ボタンのラベル | data-label="購入する" |
| data-email | 決済時に入力が必要となるメールアドレスを予め指定 | data-email="sample@example.com" |
| data-allow-remember-me | 決済情報の保存機能を利用するかどうか | data-allow-remember-me="false" |

##決済処理実装

```charges_controller.rb
class ChargesController < ApplicationController

  def create
    @product = Product.find(params[:id])
    customer = Stripe::Customer.create({
      email: params[:stripeEmail],
      source: params[:stripeToken],
    })
    charge = Stripe::Charge.create({
      customer: customer.id,
      amount: @product.price,
      description: "商品ID:#{@product.id} 商品名:#{@product.name}",
      currency: "jpy",
    })
    #rails側の売れたとき処理
    if @product.update(sold_flg: true)
      redirect_to product_path(params[:id]), notice: "商品を購入しました！"
    end
  rescue Stripe::CardError => e
    flash[:error] = e.message
    redirect_to new_charge_path
  end
end
```

コントローラのコードはほぼほぼ公式のサンプルコードと同じです。

`:id`は商品のidを渡しているので`@product`に対象の商品情報を格納します。

`Stripe::Customer.create`メソッド内ではstripe内でのユーザーを作成しています。
公式のサンプルコードと全く同じで問題ないです。
ただし、クレジット情報を保存していてそのクレジット番号を使うときは`stripeToken`を取得する処理が必要です。今回はその説明は除外します。

`Stripe::Charge.create`は課金情報を保存します。

<img width="803" alt="スクリーンショット 2019-06-02 0.01.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399745/13dcb307-d4d5-0dcc-b5e4-936fde44296f.png">

stripeにログインして支払い画面を開くとこのように支払い情報が表示されます。この情報を保存しています。

`@product.update(sold_flg: true)`の処理はrails側で売れましたよっていう処理です。stripeの説明とはあまり関係ないので簡易的な処理にしてます。仕様に沿って実装してください。

##起動してみる

`PUBLISHABLE_KEY`と`SECRET_KEY`は[こちら](https://dashboard.stripe.com/account/apikeys)からログインしてコピってください。

```
PUBLISHABLE_KEY=pk_test_~~~~~~~~~~ \
SECRET_KEY=sk_test_~~~~~~~~~~ rails s
```

これで起動できるのですが、毎回このコマンドで起動するのは面倒という方は

stripe.rb作成してあげて

```config/initializers/stripe.rb
Rails.configuration.stripe = {
  publishable_key: ENV["PUBLISHABLE_KEY"],
  secret_key: ENV["SECRET_KEY"],
}
Stripe.api_key = Rails.configuration.stripe[:secret_key]
```

Gemを追加します。

```Gemfile
group :development, :test do
  #中略
  gem "dotenv-rails"
end
```

`bundle install`してあげて、ルートディレクトリに`.envファイル`を作成し、

```.env
PUBLISHABLE_KEY="pk_test_~~~~~~~~~~~"
SECRET_KEY="sk_test_~~~~~~~~~~~~"
```

これで`rails s`でいけるでしょう。
`.envファイル`は開発時だけしか使わないと思うのでgitでは除外しておくとよいです。
デプロイ時にも不要です。

##herokuにデプロイ

```sh
$ heroku create アプリ名
$ heroku config:set PUBLISHABLE_KEY=pk_test_~~~~~~~~~~ SECRET_KEY=sk_test_~~~~~~~~~
$ git push heroku master
$ heroku open
```

これだけ！

##おわり

おわり:sleeping: