Help us understand the problem. What is going on with this article?

フリマアプリ購入機能実装(pay.jp)購入編

前回の記事の続きです。

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

前提条件

・devise/hamlが導入済みでログインができている
・payjpのアカウントが既に取得できていて、ユーザーとカードの登録が完了しており、cardテーブルに以下の情報が登録されている
user_id ... UserテーブルのID
customer_id ... payjpの顧客ID
card_id ... payjpのデフォルトカードID
顧客IDとデフォルトカードIDは以下の画面で顧客ごとに確認できます。
alt

1.コントローラーを作成しよう

コントローラとビュー(indexとdone)を作成するため、下記コマンドを実行します。

$ 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"} 購入する

*exp_monthはカードの期限月、exp_yearは期限年、last4はカードの下4桁を取得
PAYJP カードオブジェクト

完了画面

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'

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が以下の様に変わります

参考

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした