9
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Pay.jpを用いた購入機能の実装

Posted at

##概要
Pay.jpを用いた購入機能の実装を備忘録としてまとめます。
修正点ありましたらご指摘お願いいたします。
Transaction(取り引き)テーブルおよびProduct(商品)テーブルをもとに作っていきます。

##前提

  • Pay.jpのアカウント作成済み
  • Pay.jpにてクレジットカード登録機能は実装済み
  • ビューはHamlで記載
  • deviseにてログイン済み

##手順

  1. Transactionテーブルを作成(購入済みの場合SOLD OUTを表示させるため)
  2. アソシエーションの設定
  3. Transactionコントローラーを作成
  4. 環境変数の設定
  5. ルーティングの設定
  6. マークアップ:購入内容確認画面
  7. マークアップ:購入完了画面
  8. マークアップ:購入済みの場合SOLD OUTを表示
  9. 購入データの確認

##Transactionテーブルを作成
今回は購入済みの場合SOLD OUTを表示させるためにTransactionテーブルを作成します。

$ rails g model Transaction
db/migrate/20200000000000_create_transactions.rb
class CreateTransactions < ActiveRecord::Migration[5.2]
  def change
    create_table :transactions do |t|
      t.references :product, null: false, foreign_key: true
      t.references :user, null: false, foreign_key: true
      t.timestamps
    end
  end
end

マイグレートを実行

$ rails db:migrate

##アソシエーションの設定

transaction.rb
class Transaction < ApplicationRecord
  belongs_to :user, optional: true
  belongs_to :product, optional: true
end

##Transactionコントローラーを作成

$ rails g controller transactions
transactions_controller.rb
class TransactionsController < ApplicationController
  require 'payjp'
  before_action :set_card, only: [:pay_index, :pay]
  before_action :set_product

  def pay_index
    @top_image = @product.images.first
    @card = @set_card.first
    if @card.blank?
      redirect_to controller: "cards", action: "new"
    else
      Payjp.api_key = ENV["PAYJP_PRIVATE_KEY"]
      customer = Payjp::Customer.retrieve(@card.customer_id)
      @default_card_information = customer.cards.retrieve(@card.card_id)
    end
  end

  def pay
    @card = @set_card.first
    Payjp.api_key = ENV['PAYJP_PRIVATE_KEY']
    Payjp::Charge.create(
    :amount => @product.price,
    :customer => @card.customer_id,
    :currency => 'jpy',
  )
  redirect_to action: 'done', product_id: @product
  end

  def done
    @top_image = @product.images.first
    Transaction.create(product_id: @product.id, user_id: current_user.id)
  end

  private

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

  def set_product
    @product = Product.find(params[:product_id])
  end

end

##環境変数の設定

コントローラ内のENV["PAYJP_PRIVATE_KEY"]は環境変数でテスト秘密鍵を設定し読み込む。
今回はdotenvとgonを利用する。

dotenv:Railsの環境変数管理
gon:JSにてRailsで定義した環境変数を使用
参考:https://qiita.com/3443/items/44202ff6504210592570#comments

※gonはCard登録機能にて使用したため今回は関係ありません

##ルーティングの設定

routes.rb
Rails.application.routes.draw do
  devise_for :users
  root "products#index"
  resources :users, only: [:edit, :update]
  resources :products
  resources :cards, only: [:new, :show, :destroy] do
    collection do
      post 'pay_show', to: 'cards#pay_show'
      post 'pay', to: 'cards#pay'
    end
  end

  ##今回の該当箇所
  resources :transactions, only: [:index] do
    collection do
      get 'pay_index', to: 'transactions#pay_index'
      post 'pay', to: 'transactions#pay'
      get 'done', to: 'transactions#done'
    end
  end

end

##マークアップ:購入内容確認画面

Image from Gyazo

pay_index.html.haml
.transaction-pay
  .transaction-pay__content
    %h2.transaction-pay__title 購入内容の確認
    .transaction-pay__item
      .transaction-pay__item-box
        = image_tag @top_image.image.url, alt:"商品画像", class: "transaction-pay__item-image"
      .transaction-pay__item-detail
        %p.transaction-pay__item-detail--name
          = @product.name
        .transaction-pay__item-detail-price
          .transaction-pay__item-detail-price--text.transaction-pay__item-detail-price--text
            = @product.price
          .transaction-pay__item-detail-price--shipping (税込)送料込み
    .transaction-pay__table
      .transaction-pay__table-inner
        .transaction-pay__table-form
          .transaction-pay__table-content
            .transaction-pay__table-pay
              %p.transaction-pay__table-pay--title 支払い金額
            .transaction-pay__table-price
              %p.transaction-pay__table-price--title%p.transaction-pay__table-price--title
                = @product.price
          .transaction-pay__table-way
            %h3 支払い方法
            .transaction-pay__table-register
              - if @default_card_information.blank?
                %i.fas.fa-plus-circle
                %span.icon-register
                = link_to "登録してください", new_card_path
              - else
                = "**** **** **** " + @default_card_information.last4
                - 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
          .transaction-pay__table-buy
            = form_tag(action: :pay, method: :post, product_id: @product) do
              %button.transaction-pay__table-buy-button 購入する

##マークアップ:購入完了画面

Image from Gyazo

done.html.haml
.transaction-done
  .transaction-done__content
    .transaction-done__text
      購入が完了しました!
    .transaction-done__image
      = image_tag @top_image.image.url, alt:"商品画像", class: "transaction-done__image--img"
    .transaction-done__title
      = @product.name
    .transaction-done__price
      .transaction-done__price--text
        = @product.price
      .transaction-done__price--info
        (送料込み)

##マークアップ:購入済みの場合SOLD OUTを表示

Image from Gyazo

show.html.haml
.product-show
  .product-show__main
    .product-show__content
      .product-show__top-content
        .product-show__item-box
          .product-show__item-box--name
            = @product.name
          .product-show__item-box__body
            .product-show__item-box__body--top-img
              = image_tag @top_image.image.url, alt:"トップ画像", class: "product-show__item-top-img"
            .product-show__item-box__body--list
              - @images.each do |image|
                .product-show__item-box__body--sub-img
                  = image_tag image.image.url, alt:"サブ画像", class: "product-show__item-sub-img"
          .product-show__item-box--price
            %span 
            = "#{@product.price}円"
            .product-show__item-box--price-detail
              %span.product-show__item-box--price-detail-text
                (税込)
              %span.product-show__item-box--price-detail-text
                = @product.delivery_charge
          .product-show__item-box--item-detail
            = @product.name
          -# 商品出品者であれば表示させない
          - if user_signed_in? && (current_user.id == @product.user_id)
          - else
            .product-show__transaction
              .product-show__transaction-box
                -# 商品購入済みであればSOLD OUT
                - if @product_id.present?
                  .product-transaction-btn
                    SOLD OUT
                - else
                  = link_to "購入画面に進む", pay_index_transactions_path(product_id: @product), class: "product-transaction-btn"

##購入データの確認
購入ができていれば下記のURLにて履歴が確認できます。
https://pay.jp/d/charges

##以上です

9
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?