フリマアプリ購入機能実装（pay.jp）購入編

[前回の記事](https://qiita.com/annayamamoto/items/d7088cdf8547a5072d9c)の続きです。

Payjp(Pay.jp)から既に顧客IDとカードIDを取得済みでの購入を想定しています。

<img src= "https://i.gyazo.com/6b5276cc094dc694257dac844857fe62.png" width=50%>

##前提条件
・devise/hamlが導入済みでログインができている
・payjpのアカウントが既に取得できていて、ユーザーとカードの登録が完了しており、cardテーブルに以下の情報が登録されている
user_id ... UserテーブルのID
customer_id ... payjpの顧客ID
card_id ... payjpのデフォルトカードID
顧客IDとデフォルトカードIDは以下の画面で顧客ごとに確認できます。
![alt](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F224314%2Ffb0692eb-442b-5d18-1ab1-7018d33fb488.png?ixlib=rb-1.2.2&auto=format&gif-q=60&q=75&w=1400&fit=max&s=26ff7c36f5d8743ba7f42f04aca5489d)

##1.コントローラーを作成しよう
コントローラとビュー（indexとdone）を作成するため、下記コマンドを実行します。

```console
$ rails g controller buyers index done
```

コントローラーの中身を編集

```app/controllers/buyers_controller.rb
class BuyersController < ApplicationController
  require 'payjp'#Payjpの読み込み
  before_action :set_card, :set_item

  def index
    if @card.blank?
      #登録された情報がない場合にカード登録画面に移動
      redirect_to new_card_path
    else
      Payjp.api_key = Rails.application.credentials[:PAYJP_PRIVATE_KEY]
      #保管した顧客IDでpayjpから情報取得
      customer = Payjp::Customer.retrieve(@card.customer_id) 
      #カード情報表示のためインスタンス変数に代入
      @default_card_information = customer.cards.retrieve(@card.card_id)
    end
  end

  def pay
    Payjp.api_key = Rails.application.credentials[:PAYJP_PRIVATE_KEY]
    Payjp::Charge.create(
      :amount => @item.price, #支払金額を引っ張ってくる
      :customer => @card.customer_id,  #顧客ID
      :currency => 'jpy',              #日本円
    )
    redirect_to done_item_buyers_path #完了画面に移動
  end

  def done
  end

  private

  def set_card
    @card = Card.find_by(user_id: current_user.id)
  end

  def set_item
    @item = Item.find(params[:item_id])
  end

end
```
set_card , set_itemの記述で、cardとitemの情報をもってきます
今回は、先ほど作成したindexから、form_tag内のaction: 'pay'で、controller内のpayを発動

##2.購入画面と完了画面を作成しよう
**購入画面**

```app/views/buyers/index.html.haml
    %h2.buy-content__title
        購入内容の確認
      .buy-content__item
        .buy-content__item__inner
          .buy-item-main
            .buy-item-image
              = image_tag "#{@item.images[0].url}", size: '64x64', class: 'buydetails-contet__image'
            .buy-item-detail
              .buy-item-name
                = @item.name
                %p.buy-price
                  = "¥#{@item.price.to_s}"
                  %span.shipping-free (税込) 送料込み
      .buy-content__item
        %form.buy-form
          .buy-price-table
            .buy-price-table__left
              支払金額
            .buy-price-table__right
              = "¥#{@item.price.to_s}"
      .buy-content__user-info
        .buy-content__user-info__inner
          %h3 支払方法
          .user-info-update
            = link_to "変更する", "#", calss:"update-btn"
          .user-info-text
          - if @default_card_information.blank?
            %br /
          - else
            = "**** **** **** " + "#{@default_card_information.last4}"
            %br
            - exp_month = @default_card_information.exp_month.to_s
            - exp_year = @default_card_information.exp_year.to_s.slice(2,3)
            = "有効期限 " + exp_month + " / " + exp_year
            %br
      .buy-content__user-info
        .buy-content__user-info__inner              
          %h3 配送先
          .user-info-update
            = link_to "変更する","#", calss:"update-btn"
          .user-info-text
            〒111-1111
            %br
            大阪府大阪市北区〇〇1-11
            %br
            山田太郎
            = form_tag(action: :pay, method: :post) do
              %button.buy-button{type:"submit"} 購入する
```

<img src= "https://i.gyazo.com/6b5276cc094dc694257dac844857fe62.png" width=50%>

*exp_monthはカードの期限月、exp_yearは期限年、last4はカードの下４桁を取得
[PAYJP カードオブジェクト](https://pay.jp/docs/api/#card%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88)

**完了画面**

```app/views/purchase/done.html.haml
%h1.buy-content__attention
        %i.far.fa-clock
          発送をお待ちください
        %h2.buy-content__attention__title
          購入が完了しました
        .buy-content__item
          .buy-content__item__inner
            .buy-item-main
              .buy-item-image
                = image_tag "#{@item.images[0].url}", size: '64x64', class: 'buydetails-contet__image'
              .buy-item-detail
                .buy-item-name
                  = @item.name
                  %p.buy-price
                    %span 
                      = "¥#{@item.price.to_s}"
                    %span
                      .shipping-free (税込) 送料込み
        .buy-content__item
          %form.buy-form
            .buy-price-table
              .buy-price-table__left
                支払金額
              .buy-price-table__right
                = "¥#{@item.price.to_s}"
            .buy-content__user-info__submit
              = link_to "トップページへ戻る", root_path, class: 'buy-content__user-info__submit__button'
```
<img src="https://i.gyazo.com/467003be6bc0eeefa9f1e5974c25e53f.png" width=50%>
##3.ルートを設定しよう

ルーティング設定ですが、商品詳細ページからitem_idを引き継ぎたかったので、下記のようにしました

```config/routes.rb

resources :items do
    resources :buyers, only: [:index] do
      collection do
        get 'done', to: 'buyers#done'
        post 'pay', to: 'buyers#pay'
      end
    end
  end
```
##購入の確認
購入が完了するとPayjpが以下の様に変わります
<img src="https://i.gyazo.com/da87e63708f758609104f5b860fd4791.png" width=80%>


##参考
https://qiita.com/takachan_coding/items/d21c0d2621368c9b0d9b
https://qiita.com/Ikuy_h/items/7232ba32e0b728ff77aa